1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Various utilities 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21 #define XtDisplay XTDISPLAY 
  25 #include "wx/apptrait.h" 
  27 #include "wx/dcmemory.h" 
  28 #include "wx/bitmap.h" 
  29 #include "wx/evtloop.h" 
  33 #if (defined(__SUNCC__) || defined(__CLCC__)) 
  38 #pragma message disable nosimpint 
  41 #include "wx/unix/execute.h" 
  46 #include "wx/motif/private.h" 
  49 #include "X11/Xresource.h" 
  52 #include "X11/Xutil.h" 
  55 #pragma message enable nosimpint 
  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" 
  71 static char *GetIniFile (char *dest
, const char *filename
); 
  74 // ============================================================================ 
  76 // ============================================================================ 
  78 // ---------------------------------------------------------------------------- 
  79 // async event processing 
  80 // ---------------------------------------------------------------------------- 
  82 // Consume all events until no more left 
  83 void wxFlushEvents(WXDisplay
* wxdisplay
) 
  85     Display 
*display 
= (Display
*)wxdisplay
; 
  88     XSync (display
, FALSE
); 
  90     while (evtLoop
.Pending()) 
  97 // ---------------------------------------------------------------------------- 
  99 // ---------------------------------------------------------------------------- 
 101 static void xt_notify_end_process(XtPointer data
, int *WXUNUSED(fid
), 
 104     wxEndProcessData 
*proc_data 
= (wxEndProcessData 
*)data
; 
 106     wxHandleProcessTermination(proc_data
); 
 108     // VZ: I think they should be the same... 
 109     wxASSERT( (int)*id 
== proc_data
->tag 
); 
 114 int wxAddProcessCallback(wxEndProcessData 
*proc_data
, int fd
) 
 116     XtInputId id 
= XtAppAddInput((XtAppContext
) wxTheApp
->GetAppContext(), 
 118                                  (XtPointer 
*) XtInputReadMask
, 
 119                                  (XtInputCallbackProc
) xt_notify_end_process
, 
 120                                  (XtPointer
) proc_data
); 
 125 // ---------------------------------------------------------------------------- 
 127 // ---------------------------------------------------------------------------- 
 131 // on OS/2, we use the wxBell from wxBase library (src/os2/utils.cpp) 
 134     // Use current setting for the bell 
 135     XBell (wxGlobalDisplay(), 0); 
 139 wxToolkitInfo
& wxGUIAppTraits::GetToolkitInfo() 
 141     static wxToolkitInfo info
; 
 143     info
.shortName 
= _T("motif"); 
 144     info
.name 
= _T("wxMotif"); 
 145 #ifdef __WXUNIVERSAL__ 
 146     info
.shortName 
<< _T("univ"); 
 147     info
.name 
<< _T("/wxUniversal"); 
 150     // This code is WRONG!! Does NOT return the 
 151     // Motif version of the libs but the X protocol 
 153     Display 
*display 
= wxGlobalDisplay(); 
 154     info
.versionMajor 
= ProtocolVersion (display
); 
 155     info
.versionMinor 
= ProtocolRevision (display
); 
 160 // ---------------------------------------------------------------------------- 
 161 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 162 // ---------------------------------------------------------------------------- 
 166 // Read $HOME for what it says is home, if not 
 167 // read $USER or $LOGNAME for user name else determine 
 168 // the Real User, then determine the Real home dir. 
 169 static char * GetIniFile (char *dest
, const char *filename
) 
 172     if (filename 
&& wxIsAbsolutePath(filename
)) 
 174         strcpy(dest
, filename
); 
 176     else if ((home 
= wxGetUserHome("")) != NULL
) 
 179         if (dest
[strlen(dest
) - 1] != '/') 
 181         if (filename 
== NULL
) 
 183             if ((filename 
= getenv ("XENVIRONMENT")) == NULL
) 
 184                 filename 
= ".Xdefaults"; 
 186         else if (*filename 
!= '.') 
 188         strcat (dest
, filename
); 
 196 static char *GetResourcePath(char *buf
, const char *name
, bool create 
= FALSE
) 
 198     if (create 
&& wxFileExists (name
) ) { 
 200         return buf
; // Exists so ... 
 206         // Put in standard place for resource files if not absolute 
 207         strcpy (buf
, DEFAULT_XRESOURCE_DIR
); 
 209         strcat (buf
, wxFileNameFromPath (name
).c_str()); 
 213         // Touch the file to create it 
 214         FILE *fd 
= fopen (buf
, "w"); 
 221 * We have a cache for writing different resource files, 
 222 * which will only get flushed when we call wxFlushResources(). 
 223 * Build up a list of resource databases waiting to be written. 
 227 wxList 
wxResourceCache (wxKEY_STRING
); 
 230 wxFlushResources (void) 
 232     char nameBuffer
[512]; 
 234     wxNode 
*node 
= wxResourceCache
.First (); 
 237         const char *file 
= node
->GetKeyString(); 
 238         // If file doesn't exist, create it first. 
 239         (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 241         XrmDatabase database 
= (XrmDatabase
) node
->Data (); 
 242         XrmPutFileDatabase (database
, nameBuffer
); 
 243         XrmDestroyDatabase (database
); 
 244         wxNode 
*next 
= node
->Next (); 
 250 static XrmDatabase wxResourceDatabase 
= 0; 
 252 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
); 
 254 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
 258     (void) GetIniFile (buffer
, file
); 
 260     XrmDatabase database
; 
 261     wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 263         database 
= (XrmDatabase
) node
->Data (); 
 266         database 
= XrmGetFileDatabase (buffer
); 
 267         wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 271     strcpy (resName
, section
.c_str()); 
 272     strcat (resName
, "."); 
 273     strcat (resName
, entry
.c_str()); 
 275     XrmPutStringResource (&database
, resName
, value
); 
 279 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
 282     sprintf(buf
, "%.4f", value
); 
 283     return wxWriteResource(section
, entry
, buf
, file
); 
 286 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
 289     sprintf(buf
, "%ld", value
); 
 290     return wxWriteResource(section
, entry
, buf
, file
); 
 293 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
 296     sprintf(buf
, "%d", value
); 
 297     return wxWriteResource(section
, entry
, buf
, file
); 
 300 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
) 
 302     if (!wxResourceDatabase
) 
 304         Display 
*display 
= wxGlobalDisplay(); 
 305         wxXMergeDatabases (wxTheApp
, display
); 
 308     XrmDatabase database
; 
 314         // Is this right? Trying to get it to look in the user's 
 315         // home directory instead of current directory -- JACS 
 316         (void) GetIniFile (buffer
, file
); 
 318         wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 320             database 
= (XrmDatabase
) node
->Data (); 
 323             database 
= XrmGetFileDatabase (buffer
); 
 324             wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 328         database 
= wxResourceDatabase
; 
 333     strcpy (buf
, section
); 
 337     Bool success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 339     // Try different combinations of upper/lower case, just in case... 
 342         buf
[0] = (isupper (buf
[0]) ? tolower (buf
[0]) : toupper (buf
[0])); 
 343         success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 351         *value 
= new char[xvalue
.size 
+ 1]; 
 352         strncpy (*value
, xvalue
.addr
, (int) xvalue
.size
); 
 358 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 361     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 364         *value 
= (float)strtod(s
, NULL
); 
 371 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 374     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 377         *value 
= strtol(s
, NULL
, 10); 
 384 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 387     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 390         // Handle True, False here 
 391         // True, Yes, Enables, Set or  Activated 
 392         if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 394         // False, No, Disabled, Reset, Cleared, Deactivated 
 395         else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 399             *value 
= (int) strtol (s
, NULL
, 10); 
 407 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
) 
 409     XrmDatabase homeDB
, serverDB
, applicationDB
; 
 410     char filenamebuf
[1024]; 
 412     char *filename 
= &filenamebuf
[0]; 
 414     wxString classname 
= theApp
->GetClassName(); 
 416     (void) strcpy (name
, "/usr/lib/X11/app-defaults/"); 
 417     (void) strcat (name
, classname
.c_str()); 
 419     /* Get application defaults file, if any */ 
 420     applicationDB 
= XrmGetFileDatabase (name
); 
 421     (void) XrmMergeDatabases (applicationDB
, &wxResourceDatabase
); 
 423     /* Merge server defaults, created by xrdb, loaded as a property of the root 
 424     * window when the server initializes and loaded into the display 
 425     * structure on XOpenDisplay; 
 426     * if not defined, use .Xdefaults 
 429     if (XResourceManagerString (display
) != NULL
) 
 431         serverDB 
= XrmGetStringDatabase (XResourceManagerString (display
)); 
 435         (void) GetIniFile (filename
, NULL
); 
 436         serverDB 
= XrmGetFileDatabase (filename
); 
 438     XrmMergeDatabases (serverDB
, &wxResourceDatabase
); 
 440     /* Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 441     * and merge into existing database 
 444     if ((environment 
= getenv ("XENVIRONMENT")) == NULL
) 
 447         environment 
= GetIniFile (filename
, NULL
); 
 448         len 
= strlen (environment
); 
 449         wxString hostname 
= wxGetHostName(); 
 451             strncat(environment
, hostname
, 1024 - len
); 
 453     homeDB 
= XrmGetFileDatabase (environment
); 
 454     XrmMergeDatabases (homeDB
, &wxResourceDatabase
); 
 460 * Not yet used but may be useful. 
 464 wxSetDefaultResources (const Widget w
, const char **resourceSpec
, const char *name
) 
 467     Display 
*dpy 
= XtDisplay (w
);    // Retrieve the display pointer 
 469     XrmDatabase rdb 
= NULL
;    // A resource data base 
 471     // Create an empty resource database 
 472     rdb 
= XrmGetStringDatabase (""); 
 474     // Add the Component resources, prepending the name of the component 
 477     while (resourceSpec
[i
] != NULL
) 
 481         sprintf (buf
, "*%s%s", name
, resourceSpec
[i
++]); 
 482         XrmPutLineResource (&rdb
, buf
); 
 485     // Merge them into the Xt database, with lowest precendence 
 489 #if (XlibSpecificationRelease>=5) 
 490         XrmDatabase db 
= XtDatabase (dpy
); 
 491         XrmCombineDatabase (rdb
, &db
, FALSE
); 
 493         XrmMergeDatabases (dpy
->db
, &rdb
); 
 501 #endif // wxUSE_RESOURCES 
 503 // ---------------------------------------------------------------------------- 
 505 // ---------------------------------------------------------------------------- 
 507 void wxGetMousePosition( int* x
, int* y 
) 
 516     XQueryPointer(wxGlobalDisplay(), 
 517                   DefaultRootWindow(wxGlobalDisplay()), 
 519                   &(xev
.x_root
), &(xev
.y_root
), 
 527 // Return TRUE if we have a colour display 
 528 bool wxColourDisplay() 
 530     return wxDisplayDepth() > 1; 
 533 // Returns depth of screen 
 536     Display 
*dpy 
= wxGlobalDisplay(); 
 538     return DefaultDepth (dpy
, DefaultScreen (dpy
)); 
 541 // Get size of display 
 542 void wxDisplaySize(int *width
, int *height
) 
 544     Display 
*dpy 
= wxGlobalDisplay(); 
 547         *width 
= DisplayWidth (dpy
, DefaultScreen (dpy
)); 
 549         *height 
= DisplayHeight (dpy
, DefaultScreen (dpy
)); 
 552 void wxDisplaySizeMM(int *width
, int *height
) 
 554     Display 
*dpy 
= wxGlobalDisplay(); 
 557         *width 
= DisplayWidthMM(dpy
, DefaultScreen (dpy
)); 
 559         *height 
= DisplayHeightMM(dpy
, DefaultScreen (dpy
)); 
 562 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 564     // This is supposed to return desktop dimensions minus any window 
 565     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 566     // for this platform please fix this function, otherwise it defaults 
 567     // to the entire desktop. 
 570     wxDisplaySize(width
, height
); 
 574 // Configurable display in wxX11 and wxMotif 
 575 static WXDisplay 
*gs_currentDisplay 
= NULL
; 
 576 static wxString gs_displayName
; 
 578 WXDisplay 
*wxGetDisplay() 
 580     if (gs_currentDisplay
) 
 581         return gs_currentDisplay
; 
 583         return wxTheApp
->GetInitialDisplay(); 
 587 bool wxSetDisplay(const wxString
& display_name
) 
 589     gs_displayName 
= display_name
; 
 591     if ( display_name
.IsEmpty() ) 
 593         gs_currentDisplay 
= NULL
; 
 601         Display 
*display 
= XtOpenDisplay((XtAppContext
) wxTheApp
->GetAppContext(), 
 602             display_name
.c_str(), 
 603             wxTheApp
->GetAppName().c_str(), 
 604             wxTheApp
->GetClassName().c_str(), 
 606 #if XtSpecificationRelease < 5 
 615             gs_currentDisplay 
= (WXDisplay
*) display
; 
 623 wxString 
wxGetDisplayName() 
 625     return gs_displayName
; 
 628 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
 630     return wxGenericFindWindowAtPoint(pt
); 
 633 // ---------------------------------------------------------------------------- 
 634 // keycode translations 
 635 // ---------------------------------------------------------------------------- 
 637 #include <X11/keysym.h> 
 639 // FIXME what about tables?? 
 641 int wxCharCodeXToWX(KeySym keySym
) 
 648             id 
= WXK_SHIFT
; break; 
 651             id 
= WXK_CONTROL
; break; 
 653             id 
= WXK_BACK
; break; 
 655             id 
= WXK_DELETE
; break; 
 657             id 
= WXK_CLEAR
; break; 
 663             id 
= WXK_RETURN
; break; 
 665             id 
= WXK_ESCAPE
; break; 
 668             id 
= WXK_PAUSE
; break; 
 670             id 
= WXK_NUMLOCK
; break; 
 672             id 
= WXK_SCROLL
; break; 
 675             id 
= WXK_HOME
; break; 
 679             id 
= WXK_LEFT
; break; 
 681             id 
= WXK_RIGHT
; break; 
 685             id 
= WXK_DOWN
; break; 
 687             id 
= WXK_NEXT
; break; 
 689             id 
= WXK_PRIOR
; break; 
 691             id 
= WXK_MENU
; break; 
 693             id 
= WXK_SELECT
; break; 
 695             id 
= WXK_CANCEL
; break; 
 697             id 
= WXK_PRINT
; break; 
 699             id 
= WXK_EXECUTE
; break; 
 701             id 
= WXK_INSERT
; break; 
 703             id 
= WXK_HELP
; break; 
 706             id 
= WXK_MULTIPLY
; break; 
 710             id 
= WXK_SUBTRACT
; break; 
 712             id 
= WXK_DIVIDE
; break; 
 714             id 
= WXK_DECIMAL
; break; 
 722             id 
= WXK_RETURN
; break; 
 724             id 
= WXK_NUMPAD0
; break; 
 726             id 
= WXK_NUMPAD1
; break; 
 728             id 
= WXK_NUMPAD2
; break; 
 730             id 
= WXK_NUMPAD3
; break; 
 732             id 
= WXK_NUMPAD4
; break; 
 734             id 
= WXK_NUMPAD5
; break; 
 736             id 
= WXK_NUMPAD6
; break; 
 738             id 
= WXK_NUMPAD7
; break; 
 740             id 
= WXK_NUMPAD8
; break; 
 742             id 
= WXK_NUMPAD9
; break; 
 792             id 
= (keySym 
<= 255) ? (int)keySym 
: -1; 
 798 KeySym 
wxCharCodeWXToX(int id
) 
 804         case WXK_CANCEL
:            keySym 
= XK_Cancel
; break; 
 805         case WXK_BACK
:              keySym 
= XK_BackSpace
; break; 
 806         case WXK_TAB
:            keySym 
= XK_Tab
; break; 
 807         case WXK_CLEAR
:        keySym 
= XK_Clear
; break; 
 808         case WXK_RETURN
:        keySym 
= XK_Return
; break; 
 809         case WXK_SHIFT
:        keySym 
= XK_Shift_L
; break; 
 810         case WXK_CONTROL
:        keySym 
= XK_Control_L
; break; 
 811         case WXK_MENU 
:        keySym 
= XK_Menu
; break; 
 812         case WXK_PAUSE
:        keySym 
= XK_Pause
; break; 
 813         case WXK_ESCAPE
:        keySym 
= XK_Escape
; break; 
 814         case WXK_SPACE
:        keySym 
= ' '; break; 
 815         case WXK_PRIOR
:        keySym 
= XK_Prior
; break; 
 816         case WXK_NEXT 
:        keySym 
= XK_Next
; break; 
 817         case WXK_END
:        keySym 
= XK_End
; break; 
 818         case WXK_HOME 
:        keySym 
= XK_Home
; break; 
 819         case WXK_LEFT 
:        keySym 
= XK_Left
; break; 
 820         case WXK_UP
:        keySym 
= XK_Up
; break; 
 821         case WXK_RIGHT
:        keySym 
= XK_Right
; break; 
 822         case WXK_DOWN 
:        keySym 
= XK_Down
; break; 
 823         case WXK_SELECT
:        keySym 
= XK_Select
; break; 
 824         case WXK_PRINT
:        keySym 
= XK_Print
; break; 
 825         case WXK_EXECUTE
:        keySym 
= XK_Execute
; break; 
 826         case WXK_INSERT
:        keySym 
= XK_Insert
; break; 
 827         case WXK_DELETE
:        keySym 
= XK_Delete
; break; 
 828         case WXK_HELP 
:        keySym 
= XK_Help
; break; 
 829         case WXK_NUMPAD0
:        keySym 
= XK_KP_0
; break; 
 830         case WXK_NUMPAD1
:        keySym 
= XK_KP_1
; break; 
 831         case WXK_NUMPAD2
:        keySym 
= XK_KP_2
; break; 
 832         case WXK_NUMPAD3
:        keySym 
= XK_KP_3
; break; 
 833         case WXK_NUMPAD4
:        keySym 
= XK_KP_4
; break; 
 834         case WXK_NUMPAD5
:        keySym 
= XK_KP_5
; break; 
 835         case WXK_NUMPAD6
:        keySym 
= XK_KP_6
; break; 
 836         case WXK_NUMPAD7
:        keySym 
= XK_KP_7
; break; 
 837         case WXK_NUMPAD8
:        keySym 
= XK_KP_8
; break; 
 838         case WXK_NUMPAD9
:        keySym 
= XK_KP_9
; break; 
 839         case WXK_MULTIPLY
:        keySym 
= XK_KP_Multiply
; break; 
 840         case WXK_ADD
:        keySym 
= XK_KP_Add
; break; 
 841         case WXK_SUBTRACT
:        keySym 
= XK_KP_Subtract
; break; 
 842         case WXK_DECIMAL
:        keySym 
= XK_KP_Decimal
; break; 
 843         case WXK_DIVIDE
:        keySym 
= XK_KP_Divide
; break; 
 844         case WXK_F1
:        keySym 
= XK_F1
; break; 
 845         case WXK_F2
:        keySym 
= XK_F2
; break; 
 846         case WXK_F3
:        keySym 
= XK_F3
; break; 
 847         case WXK_F4
:        keySym 
= XK_F4
; break; 
 848         case WXK_F5
:        keySym 
= XK_F5
; break; 
 849         case WXK_F6
:        keySym 
= XK_F6
; break; 
 850         case WXK_F7
:        keySym 
= XK_F7
; break; 
 851         case WXK_F8
:        keySym 
= XK_F8
; break; 
 852         case WXK_F9
:        keySym 
= XK_F9
; break; 
 853         case WXK_F10
:        keySym 
= XK_F10
; break; 
 854         case WXK_F11
:        keySym 
= XK_F11
; break; 
 855         case WXK_F12
:        keySym 
= XK_F12
; break; 
 856         case WXK_F13
:        keySym 
= XK_F13
; break; 
 857         case WXK_F14
:        keySym 
= XK_F14
; break; 
 858         case WXK_F15
:        keySym 
= XK_F15
; break; 
 859         case WXK_F16
:        keySym 
= XK_F16
; break; 
 860         case WXK_F17
:        keySym 
= XK_F17
; break; 
 861         case WXK_F18
:        keySym 
= XK_F18
; break; 
 862         case WXK_F19
:        keySym 
= XK_F19
; break; 
 863         case WXK_F20
:        keySym 
= XK_F20
; break; 
 864         case WXK_F21
:        keySym 
= XK_F21
; break; 
 865         case WXK_F22
:        keySym 
= XK_F22
; break; 
 866         case WXK_F23
:        keySym 
= XK_F23
; break; 
 867         case WXK_F24
:        keySym 
= XK_F24
; break; 
 868         case WXK_NUMLOCK
:    keySym 
= XK_Num_Lock
; break; 
 869         case WXK_SCROLL
:     keySym 
= XK_Scroll_Lock
; break; 
 870         default:             keySym 
= id 
<= 255 ? (KeySym
)id 
: 0; 
 876 // ---------------------------------------------------------------------------- 
 877 // Some colour manipulation routines 
 878 // ---------------------------------------------------------------------------- 
 880 void wxHSVToXColor(wxHSV 
*hsv
,XColor 
*rgb
) 
 885     int r 
= 0, g 
= 0, b 
= 0; 
 888     s 
= (s 
* wxMAX_RGB
) / wxMAX_SV
; 
 889     v 
= (v 
* wxMAX_RGB
) / wxMAX_SV
; 
 891     if (s 
== 0) { h 
= 0; r 
= g 
= b 
= v
; } 
 894     p 
= v 
* (wxMAX_RGB 
- s
) / wxMAX_RGB
; 
 895     q 
= v 
* (wxMAX_RGB 
- s 
* f 
/ 60) / wxMAX_RGB
; 
 896     t 
= v 
* (wxMAX_RGB 
- s 
* (60 - f
) / 60) / wxMAX_RGB
; 
 899     case 0: r 
= v
, g 
= t
, b 
= p
; break; 
 900     case 1: r 
= q
, g 
= v
, b 
= p
; break; 
 901     case 2: r 
= p
, g 
= v
, b 
= t
; break; 
 902     case 3: r 
= p
, g 
= q
, b 
= v
; break; 
 903     case 4: r 
= t
, g 
= p
, b 
= v
; break; 
 904     case 5: r 
= v
, g 
= p
, b 
= q
; break; 
 911 void wxXColorToHSV(wxHSV 
*hsv
,XColor 
*rgb
) 
 913     int r 
= rgb
->red 
>> 8; 
 914     int g 
= rgb
->green 
>> 8; 
 915     int b 
= rgb
->blue 
>> 8; 
 916     int maxv 
= wxMax3(r
, g
, b
); 
 917     int minv 
= wxMin3(r
, g
, b
); 
 920     if (maxv
) s 
= (maxv 
- minv
) * wxMAX_RGB 
/ maxv
; 
 925         int rc
, gc
, bc
, hex 
= 0; 
 926         rc 
= (maxv 
- r
) * wxMAX_RGB 
/ (maxv 
- minv
); 
 927         gc 
= (maxv 
- g
) * wxMAX_RGB 
/ (maxv 
- minv
); 
 928         bc 
= (maxv 
- b
) * wxMAX_RGB 
/ (maxv 
- minv
); 
 929         if (r 
== maxv
) { h 
= bc 
- gc
, hex 
= 0; } 
 930         else if (g 
== maxv
) { h 
= rc 
- bc
, hex 
= 2; } 
 931         else if (b 
== maxv
) { h 
= gc 
- rc
, hex 
= 4; } 
 932         h 
= hex 
* 60 + (h 
* 60 / wxMAX_RGB
); 
 936     hsv
->s 
= (s 
* wxMAX_SV
) / wxMAX_RGB
; 
 937     hsv
->v 
= (v 
* wxMAX_SV
) / wxMAX_RGB
; 
 940 void wxAllocNearestColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
 945     int screen 
= DefaultScreen(d
); 
 946     int num_colors 
= DisplayCells(d
,screen
); 
 948     XColor 
*color_defs 
= new XColor
[num_colors
]; 
 949     for(llp 
= 0;llp 
< num_colors
;llp
++) color_defs
[llp
].pixel 
= llp
; 
 950     XQueryColors(d
,cmp
,color_defs
,num_colors
); 
 953     wxXColorToHSV(&hsv
,xc
); 
 955     int diff
, min_diff 
= 0, pixel 
= 0; 
 957     for(llp 
= 0;llp 
< num_colors
;llp
++) 
 959         wxXColorToHSV(&hsv_defs
,&color_defs
[llp
]); 
 960         diff 
= wxSIGN(wxH_WEIGHT 
* (hsv
.h 
- hsv_defs
.h
)) + 
 961             wxSIGN(wxS_WEIGHT 
* (hsv
.s 
- hsv_defs
.s
)) + 
 962             wxSIGN(wxV_WEIGHT 
* (hsv
.v 
- hsv_defs
.v
)); 
 963         if (llp 
== 0) min_diff 
= diff
; 
 964         if (min_diff 
> diff
) { min_diff 
= diff
; pixel 
= llp
; } 
 965         if (min_diff 
== 0) break; 
 968     xc 
-> red 
= color_defs
[pixel
].red
; 
 969     xc 
-> green 
= color_defs
[pixel
].green
; 
 970     xc 
-> blue 
= color_defs
[pixel
].blue
; 
 971     xc 
-> flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 974     if (!XAllocColor(d,cmp,xc)) 
 975         cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n"; 
 982 void wxAllocColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
 984     if (!XAllocColor(d
,cmp
,xc
)) 
 986         //          cout << "wxAllocColor : Warning : Can not allocate color, attempt find nearest !\n"; 
 987         wxAllocNearestColor(d
,cmp
,xc
); 
 992 wxString 
wxGetXEventName(XEvent
& event
) 
 995     wxString 
str(wxT("(some event)")); 
 998     int type 
= event
.xany
.type
; 
 999             static char* event_name
[] = { 
1000                 "", "unknown(-)",                                         // 0-1 
1001                 "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", // 2-5 
1002                 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn",  // 6-9 
1003                 "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose",   // 10-13 
1004                 "NoExpose", "VisibilityNotify", "CreateNotify",           // 14-16 
1005                 "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",// 17-20 
1006                 "ReparentNotify", "ConfigureNotify", "ConfigureRequest",  // 21-23 
1007                 "GravityNotify", "ResizeRequest", "CirculateNotify",      // 24-26 
1008                 "CirculateRequest", "PropertyNotify", "SelectionClear",   // 27-29 
1009                 "SelectionRequest", "SelectionNotify", "ColormapNotify",  // 30-32 
1010                 "ClientMessage", "MappingNotify",                         // 33-34 
1011                 "unknown(+)"};                                            // 35 
1012             type 
= wxMin(35, type
); type 
= wxMax(1, type
); 
1013         wxString 
str(event_name
[type
]); 
1019 // ---------------------------------------------------------------------------- 
1021 // ---------------------------------------------------------------------------- 
1023 // Find the letter corresponding to the mnemonic, for Motif 
1024 char wxFindMnemonic (const char *s
) 
1027     int len 
= strlen (s
); 
1030     for (i 
= 0; i 
< len
; i
++) 
1034             // Carefully handle && 
1035             if ((i 
+ 1) <= len 
&& s
[i 
+ 1] == '&') 
1047 char* wxFindAccelerator( const char *s 
) 
1050     // VZ: this function returns incorrect keysym which completely breaks kbd 
1054     // The accelerator text is after the \t char. 
1055     s 
= strchr( s
, '\t' ); 
1057     if( !s 
) return NULL
; 
1060     Now we need to format it as X standard: 
1065         Ctrl+N       --> Ctrl<Key>N 
1066         Alt+k        --> Meta<Key>k 
1067         Ctrl+Shift+A --> Ctrl Shift<Key>A 
1069         and handle Ctrl-N & similia 
1072     static char buf
[256]; 
1075     wxString tmp 
= s 
+ 1; // skip TAB 
1078     while( index 
< tmp
.length() ) 
1080         size_t plus  
= tmp
.find( '+', index 
); 
1081         size_t minus 
= tmp
.find( '-', index 
); 
1083         // neither '+' nor '-', add <Key> 
1084         if( plus 
== wxString::npos 
&& minus 
== wxString::npos 
) 
1086             strcat( buf
, "<Key>" ); 
1087             strcat( buf
, tmp
.c_str() + index 
); 
1092         // OK: npos is big and positive 
1093         size_t sep 
= wxMin( plus
, minus 
); 
1094         wxString mod 
= tmp
.substr( index
, sep 
- index 
); 
1105         strcat( buf
, mod
.c_str() ); 
1114 XmString 
wxFindAcceleratorText (const char *s
) 
1117     // VZ: this function returns incorrect keysym which completely breaks kbd 
1121     // The accelerator text is after the \t char. 
1122     s 
= strchr( s
, '\t' ); 
1124     if( !s 
) return NULL
; 
1126     return wxStringToXmString( s 
+ 1 ); // skip TAB! 
1130 // Change a widget's foreground and background colours. 
1131 void wxDoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
) 
1133     // When should we specify the foreground, if it's calculated 
1134     // by wxComputeColours? 
1135     // Solution: say we start with the default (computed) foreground colour. 
1136     // If we call SetForegroundColour explicitly for a control or window, 
1137     // then the foreground is changed. 
1138     // Therefore SetBackgroundColour computes the foreground colour, and 
1139     // SetForegroundColour changes the foreground colour. The ordering is 
1142     XtVaSetValues ((Widget
) widget
, 
1143         XmNforeground
, foregroundColour
.AllocColour(XtDisplay((Widget
) widget
)), 
1147 void wxDoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
) 
1149     wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
, 
1152     XtVaSetValues ((Widget
) widget
, 
1153         XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
, 
1154         XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
, 
1155         XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
, 
1156         XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
, 
1159     if (changeArmColour
) 
1160         XtVaSetValues ((Widget
) widget
, 
1161         XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
, 
1165 extern void wxDoChangeFont(WXWidget widget
, wxFont
& font
) 
1167     // Lesstif 0.87 hangs here, but 0.93 does not 
1168 #if !wxCHECK_LESSTIF() || wxCHECK_LESSTIF_VERSION( 0, 93 ) 
1169     Widget w 
= (Widget
)widget
; 
1171                    wxFont::GetFontTag(), font
.GetFontType( XtDisplay(w
) ), 
1177 wxString 
wxXmStringToString( const XmString
& xmString 
) 
1180     if( XmStringGetLtoR( xmString
, XmSTRING_DEFAULT_CHARSET
, &txt 
) ) 
1187     return wxEmptyString
; 
1190 XmString 
wxStringToXmString( const wxString
& str 
) 
1192     return XmStringCreateLtoR((char *)str
.c_str(), XmSTRING_DEFAULT_CHARSET
); 
1195 XmString 
wxStringToXmString( const char* str 
) 
1197     return XmStringCreateLtoR((char *)str
, XmSTRING_DEFAULT_CHARSET
); 
1200 // ---------------------------------------------------------------------------- 
1201 // wxBitmap utility functions 
1202 // ---------------------------------------------------------------------------- 
1204 // Creates a bitmap with transparent areas drawn in 
1205 // the given colour. 
1206 wxBitmap 
wxCreateMaskedBitmap(const wxBitmap
& bitmap
, wxColour
& colour
) 
1208     wxBitmap 
newBitmap(bitmap
.GetWidth(), 
1214     srcDC
.SelectObject(bitmap
); 
1215     destDC
.SelectObject(newBitmap
); 
1217     wxBrush 
brush(colour
, wxSOLID
); 
1218     // destDC.SetOptimization(FALSE); 
1219     destDC
.SetBackground(brush
); 
1221     destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), 
1222                 &srcDC
, 0, 0, wxCOPY
, TRUE
); 
1227 // ---------------------------------------------------------------------------- 
1228 // Miscellaneous functions 
1229 // ---------------------------------------------------------------------------- 
1231 WXWidget 
wxCreateBorderWidget( WXWidget parent
, long style 
) 
1233     Widget borderWidget 
= (Widget
)NULL
, parentWidget 
= (Widget
)parent
; 
1235     if (style 
& wxSIMPLE_BORDER
) 
1237         borderWidget 
= XtVaCreateManagedWidget
 
1240                                     xmFrameWidgetClass
, parentWidget
, 
1241                                     XmNshadowType
, XmSHADOW_ETCHED_IN
, 
1242                                     XmNshadowThickness
, 1, 
1246     else if (style 
& wxSUNKEN_BORDER
) 
1248         borderWidget 
= XtVaCreateManagedWidget
 
1251                                     xmFrameWidgetClass
, parentWidget
, 
1252                                     XmNshadowType
, XmSHADOW_IN
, 
1256     else if (style 
& wxRAISED_BORDER
) 
1258         borderWidget 
= XtVaCreateManagedWidget
 
1261                                     xmFrameWidgetClass
, parentWidget
, 
1262                                     XmNshadowType
, XmSHADOW_OUT
, 
1267     return borderWidget
;