1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: saldisp.cxx,v $
10 * $Revision: 1.101.30.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
36 // -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
50 #if defined(SOLARIS) || defined(IRIX)
51 #include <sal/alloca.h>
52 #include <osl/module.h>
55 #include <tools/prex.h>
56 #include <X11/cursorfont.h>
57 #include "salcursors.h"
62 #include <X11/keysym.h>
64 #include <X11/Xatom.h>
67 #ifdef USE_XINERAMA_XORG
68 #if defined(X86) || defined(X86_64)
69 #include <X11/extensions/Xinerama.h>
71 #elif defined USE_XINERAMA_XSUN
72 #if defined(SOLARIS) && defined(INTEL) // missing extension header in standard installation
73 #define MAXFRAMEBUFFERS 16
74 Bool
XineramaGetState(Display
*, int);
75 Status
XineramaGetInfo(Display
*, int, XRectangle
*, unsigned char*, int*);
77 #include <X11/extensions/xinerama.h>
80 #error USE_XINERAMA but no xinerama version
84 #if __XTestExtension__
85 #include <X11/extensions/XTest.h>
86 #include <X11/extensions/XKB.h>
87 #include <X11/XKBlib.h>
90 #include <tools/postx.h>
93 #include <sal/types.h>
94 #include "i18n_im.hxx"
95 #include "i18n_xkb.hxx"
96 #include <saldisp.hxx>
97 #include <saldata.hxx>
98 #include <vcl/salinst.hxx>
100 #include <salframe.h>
101 #include <vcl/keycodes.hxx>
102 #include <vcl/salbtype.hxx>
104 #ifndef _OSL_THREADMUTEX_H_
105 #include <osl/mutex.h>
109 #include <wmadaptor.hxx>
112 #include <osl/socket.h>
116 using namespace vcl_sal
;
118 // -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
119 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
120 #define PSEUDOCOLOR12
128 #define SALCOLOR_WHITE MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF )
129 #define SALCOLOR_BLACK MAKE_SALCOLOR( 0x00, 0x00, 0x00 )
131 // -=-= Prototyps =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
132 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
133 // -=-= static variables -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
134 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
135 static const char* const VisualClassName
[] = {
144 static const char* const EventNames
[] =
183 // -=-= global inline =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
184 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
185 inline const char *Null( const char *p
) { return p
? p
: ""; }
186 inline const char *GetEnv( const char *p
) { return Null( getenv( p
) ); }
187 inline const char *KeyStr( KeySym n
) { return Null( XKeysymToString( n
) ); }
189 inline const char *GetAtomName( Display
*d
, Atom a
)
190 { return Null( XGetAtomName( d
, a
) ); }
192 inline double Hypothenuse( long w
, long h
)
193 { return sqrt( (double)((w
*w
)+(h
*h
)) ); }
195 inline int ColorDiff( int r
, int g
, int b
)
196 { return (r
*r
)+(g
*g
)+(b
*b
); }
198 inline int ColorDiff( SalColor c1
, int r
, int g
, int b
)
199 { return ColorDiff( (int)SALCOLOR_RED (c1
)-r
,
200 (int)SALCOLOR_GREEN(c1
)-g
,
201 (int)SALCOLOR_BLUE (c1
)-b
); }
203 // -=-= global functions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
204 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
205 static int sal_Shift( Pixel nMask
)
208 if( nMask
< 0x00010000 ) { nMask
<<= 16; i
-= 16; }
209 if( nMask
< 0x01000000 ) { nMask
<<= 8; i
-= 8; }
210 if( nMask
< 0x10000000 ) { nMask
<<= 4; i
-= 4; }
211 if( nMask
< 0x40000000 ) { nMask
<<= 2; i
-= 2; }
212 if( nMask
< 0x80000000 ) { nMask
<<= 1; i
-= 1; }
216 static int sal_significantBits( Pixel nMask
)
218 int nRotate
= sizeof(Pixel
)*4;
229 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
230 static BOOL
sal_GetVisualInfo( Display
*pDisplay
, XID nVID
, XVisualInfo
&rVI
)
233 XVisualInfo aTemplate
;
236 aTemplate
.visualid
= nVID
;
238 pInfos
= XGetVisualInfo( pDisplay
, VisualIDMask
, &aTemplate
, &nInfos
);
245 DBG_ASSERT( rVI
.visualid
== nVID
,
246 "sal_GetVisualInfo: could not get correct visual by visualId" );
250 // ---------------------------------------------------------------------------
252 // check wether displaystring is in format N.M or N. or just N
253 // with N and M beeing natural numbers
255 sal_IsDisplayNumber( const char *pDisplayString
)
257 if ( ! isdigit(*pDisplayString
) )
259 while ( isdigit(*(++pDisplayString
)) )
262 if ( *pDisplayString
== '.' )
264 while ( isdigit(*(++pDisplayString
)) )
268 return (*pDisplayString
== '\0');
271 // check whether host1 and host2 point to the same ip address
273 sal_EqualHosts( const OUString
& Host1
, const OUString
& Host2
)
275 oslSocketAddr pHostAddr1
;
276 oslSocketAddr pHostAddr2
;
277 BOOL bEqualAddress
= FALSE
;
279 if ( Host1
.toChar() >= '0' && Host1
.toChar() <= '9' )
280 pHostAddr1
= osl_createInetSocketAddr( Host1
.pData
, 0 );
282 pHostAddr1
= osl_resolveHostname( Host1
.pData
);
284 if ( Host2
.toChar() >= '0' && Host2
.toChar() <= '9' )
285 pHostAddr2
= osl_createInetSocketAddr( Host2
.pData
, 0 );
287 pHostAddr2
= osl_resolveHostname( Host2
.pData
);
289 if( pHostAddr1
&& pHostAddr2
)
290 bEqualAddress
= osl_isEqualSocketAddr( pHostAddr1
, pHostAddr2
) ? TRUE
: FALSE
;
293 osl_destroySocketAddr( pHostAddr1
);
295 osl_destroySocketAddr( pHostAddr2
);
297 return bEqualAddress
;
301 sal_IsLocalDisplay( Display
*pDisplay
)
303 const char *pDisplayString
= DisplayString( pDisplay
);
305 // no string, no idea
306 if ( pDisplayString
== NULL
|| pDisplayString
[ 0 ] == '\0')
310 if ( pDisplayString
[ 0 ] == ':' )
311 return sal_IsDisplayNumber( pDisplayString
+ 1 );
313 // check for fixed token which all mean localhost:x.y
314 const char pLocal
[] = "localhost:";
315 const int nLocalLen
= sizeof(pLocal
) - 1;
316 if ( strncmp(pDisplayString
, pLocal
, nLocalLen
) == 0 )
317 return sal_IsDisplayNumber( pDisplayString
+ nLocalLen
);
319 const char pUnix
[] = "unix:";
320 const int nUnixLen
= sizeof(pUnix
) - 1;
321 if ( strncmp(pDisplayString
, pUnix
, nUnixLen
) == 0 )
322 return sal_IsDisplayNumber( pDisplayString
+ nUnixLen
);
324 const char pLoopback
[] = "127.0.0.1:";
325 const int nLoopbackLen
= sizeof(pLoopback
) - 1;
326 if ( strncmp(pDisplayString
, pLoopback
, nLoopbackLen
) == 0 )
327 return sal_IsDisplayNumber( pDisplayString
+ nLoopbackLen
);
329 // compare local hostname to displaystring, both may be ip address or
332 char *pDisplayHost
= strdup( pDisplayString
);
333 char *pPtr
= strrchr( pDisplayHost
, ':' );
337 OUString aLocalHostname
;
338 if( osl_getLocalHostname( &aLocalHostname
.pData
) == osl_Socket_Ok
)
341 OUString
aDisplayHostname( pDisplayHost
, strlen( pDisplayHost
), osl_getThreadTextEncoding() );
342 bEqual
= sal_EqualHosts( aLocalHostname
, aDisplayHostname
);
343 bEqual
= bEqual
&& sal_IsDisplayNumber( pPtr
+ 1 );
346 free( pDisplayHost
);
351 // ---------------------------------------------------------------------------
352 // IsLocal means soffice is running on the same host as the xserver
353 // since it is not called very often and sal_IsLocalDisplay() is relative
354 // expensive bLocal_ is initialized on first call
356 BOOL
SalDisplay::IsLocal()
358 if ( ! mbLocalIsValid
)
360 bLocal_
= sal_IsLocalDisplay( pDisp_
);
361 mbLocalIsValid
= TRUE
;
363 return (BOOL
)bLocal_
;
366 // ---------------------------------------------------------------------------
367 extern "C" srv_vendor_t
368 sal_GetServerVendor( Display
*p_display
)
371 srv_vendor_t e_vendor
; // vendor as enum
372 const char *p_name
; // vendor name as returned by VendorString()
373 unsigned int n_len
; // number of chars to compare
376 const vendor_t p_vendorlist
[] = {
377 { vendor_xfree
, "The XFree86 Project, Inc", 13 },
378 { vendor_sun
, "Sun Microsystems, Inc.", 10 },
379 { vendor_attachmate
, "Attachmate Corporation", 10 },
381 "DECWINDOWS DigitalEquipmentCorporation, eXcursion", 42 },
382 { vendor_hp
, "Hewlett-Packard Company", 17 },
383 { vendor_hummingbird
, "Hummingbird Communications Ltd.", 11 },
384 { vendor_ibm
, "International Business Machines", 24 },
385 { vendor_sgi
, "Silicon Graphics", 9 },
386 { vendor_sco
, "The Santa Cruz Operation", 16 },
387 { vendor_xinside
, "X Inside Inc.", 10 },
388 // allways the last entry: vendor_none to indicate eol
389 { vendor_none
, NULL
, 0 },
392 #ifdef _USE_PRINT_EXTENSION_
393 if ( ! XSalIsDisplay( p_display
) )
394 return vendor_xprinter
;
397 // handle regular server vendors
398 char *p_name
= ServerVendor( p_display
);
400 for (p_vendor
= const_cast<vendor_t
*>(p_vendorlist
); p_vendor
->e_vendor
!= vendor_none
; p_vendor
++)
402 if ( strncmp (p_name
, p_vendor
->p_name
, p_vendor
->n_len
) == 0 )
403 return p_vendor
->e_vendor
;
406 // vendor not found in list
407 return vendor_unknown
;
410 static sal_Bool
sal_IsTrustedSolaris (Display
*p_display
)
412 int n_numextensions
= 0;
413 char **p_extensions
= XListExtensions (p_display
, &n_numextensions
);
414 sal_Bool b_is
= sal_False
;
416 if (p_extensions
!= NULL
)
418 for (int i
= 0; !b_is
&& i
< n_numextensions
; i
++)
419 b_is
= (strcmp (p_extensions
[i
], "SUN_TSOL") == 0);
420 XFreeExtensionList (p_extensions
);
426 // -=-= SalDisplay -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
427 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
428 BOOL
SalDisplay::BestVisual( Display
*pDisplay
,
432 VisualID nDefVID
= XVisualIDFromVisual( DefaultVisual( pDisplay
, nScreen
) );
434 char *pVID
= getenv( "SAL_VISUAL" );
436 sscanf( pVID
, "%li", &nVID
);
438 if( nVID
&& sal_GetVisualInfo( pDisplay
, nVID
, rVI
) )
439 return rVI
.visualid
== nDefVID
;
442 aVI
.screen
= nScreen
;
445 XVisualInfo
* pVInfos
= XGetVisualInfo( pDisplay
, VisualScreenMask
,
447 // pVInfos should contain at least one visual, otherwise
449 int* pWeight
= (int*)alloca( sizeof(int)*nVisuals
);
451 for( i
= 0; i
< nVisuals
; i
++ )
453 BOOL bUsable
= FALSE
;
456 if ( pVInfos
[i
].screen
!= nScreen
)
461 if( pVInfos
[i
].c_class
== TrueColor
)
464 if( pVInfos
[i
].depth
== 24 )
467 else if( pVInfos
[i
].depth
== 8 )
469 nTrueColor
= -1; // strongly discourage 8 bit true color
474 else if( pVInfos
[i
].depth
== 15 )
478 else if( pVInfos
[i
].depth
== 16 )
482 else if( pVInfos
[i
].depth
== 32 )
485 // we do not have use for an alpha channel
486 // better use a 24 or 16 bit truecolor visual if possible
491 else if( pVInfos
[i
].c_class
== PseudoColor
)
493 if( pVInfos
[i
].depth
<= 8 )
496 else if( pVInfos
[i
].depth
== 12 )
500 pWeight
[ i
] = bUsable
? nTrueColor
*pVInfos
[i
].depth
: -1024;
501 pWeight
[ i
] -= pVInfos
[ i
].visualid
;
505 int nBestWeight
= -1024;
506 for( i
= 0; i
< nVisuals
; i
++ )
508 if( pWeight
[ i
] > nBestWeight
)
510 nBestWeight
= pWeight
[ i
];
515 rVI
= pVInfos
[ nBestVisual
];
518 return rVI
.visualid
== nDefVID
;
521 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
523 SalDisplay::SalDisplay( Display
*display
) :
524 mpInputMethod( NULL
),
525 mpFallbackFactory ( NULL
),
527 m_pWMAdaptor( NULL
),
528 m_pDtIntegrator( NULL
),
529 m_bUseRandRWrapper( true ),
530 m_nLastUserEventTime( CurrentTime
)
532 #if OSL_DEBUG_LEVEL > 1
533 fprintf( stderr
, "SalDisplay::SalDisplay()\n" );
535 X11SalData
*pSalData
= GetX11SalData();
537 DBG_ASSERT( ! pSalData
->GetDisplay(), "Second SalDisplay created !!!\n" );
538 pSalData
->SetSalDisplay( this );
540 pXLib_
= pSalData
->GetLib();
541 m_nDefaultScreen
= DefaultScreen( pDisp_
);
545 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
546 SalDisplay::~SalDisplay( )
548 #if OSL_DEBUG_LEVEL > 1
549 fprintf( stderr
, "SalDisplay::~SalDisplay()\n" );
554 #if OSL_DEBUG_LEVEL > 1
555 fprintf( stderr
, "display %p closed\n", pDisp_
);
559 // don't do this in doDestruct since RandR extension adds hooks into Display
560 // that is XCloseDisplay still needs the RandR library if it was used
564 void SalDisplay::doDestruct()
566 X11SalData
*pSalData
= GetX11SalData();
570 delete m_pDtIntegrator
;
571 m_pDtIntegrator
= NULL
;
572 X11SalBitmap::ImplDestroyCache();
573 X11SalGraphics::releaseGlyphPeer();
578 delete mpInputMethod
, mpInputMethod
= (SalI18N_InputMethod
*)ILLEGAL_POINTER
;
579 delete mpKbdExtension
, mpKbdExtension
= (SalI18N_KeyboardExtension
*)ILLEGAL_POINTER
;
581 // do not call anything that could implicitly call back into
582 // this object after this point
583 osl_destroyMutex( hEventGuard_
);
585 for( unsigned int i
= 0; i
< m_aScreens
.size(); i
++ )
587 ScreenData
& rData
= m_aScreens
[i
];
590 if( rData
.m_aMonoGC
!= rData
.m_aCopyGC
)
591 XFreeGC( pDisp_
, rData
.m_aMonoGC
);
592 XFreeGC( pDisp_
, rData
.m_aCopyGC
);
593 XFreeGC( pDisp_
, rData
.m_aAndInvertedGC
);
594 XFreeGC( pDisp_
, rData
.m_aAndGC
);
595 XFreeGC( pDisp_
, rData
.m_aOrGC
);
596 XFreeGC( pDisp_
, rData
.m_aStippleGC
);
597 XFreePixmap( pDisp_
, rData
.m_hInvert50
);
598 XDestroyWindow( pDisp_
, rData
.m_aRefWindow
);
599 Colormap aColMap
= rData
.m_aColormap
.GetXColormap();
600 if( aColMap
!= None
&& aColMap
!= DefaultColormap( pDisp_
, i
) )
601 XFreeColormap( pDisp_
, aColMap
);
605 hEventGuard_
= (oslMutex
)ILLEGAL_POINTER
;
607 for( size_t i
= 0; i
< POINTER_COUNT
; i
++ )
609 if( aPointerCache_
[i
] )
610 XFreeCursor( pDisp_
, aPointerCache_
[i
] );
613 pXLib_
->Remove( ConnectionNumber( pDisp_
) );
616 if( pSalData
->GetDisplay() == this )
617 pSalData
->SetSalDisplay( NULL
);
620 static int DisplayHasEvent( int
624 , SalX11Display
*pDisplay
)
626 DBG_ASSERT( ConnectionNumber( pDisplay
->GetDisplay() ) == fd
,
627 "wrong fd in DisplayHasEvent" );
628 if( ! pDisplay
->IsDisplay() )
631 vos::IMutex
* pSalInstYieldMutex
=
632 GetSalData()->m_pInstance
->GetYieldMutex();
633 ::vos::OGuard
aGuard( *pSalInstYieldMutex
);
634 return pDisplay
->IsEvent();
636 static int DisplayQueue( int
640 , SalX11Display
*pDisplay
)
642 DBG_ASSERT( ConnectionNumber( pDisplay
->GetDisplay() ) == fd
,
643 "wrong fd in DisplayHasEvent" );
644 vos::IMutex
* pSalInstYieldMutex
=
645 GetSalData()->m_pInstance
->GetYieldMutex();
646 ::vos::OGuard
aGuard( *pSalInstYieldMutex
);
647 return XEventsQueued( pDisplay
->GetDisplay(),
648 QueuedAfterReading
);
650 static int DisplayYield( int
654 , SalX11Display
*pDisplay
)
656 DBG_ASSERT( ConnectionNumber( pDisplay
->GetDisplay() ) == fd
,
657 "wrong fd in DisplayHasEvent" );
658 vos::IMutex
* pSalInstYieldMutex
=
659 GetSalData()->m_pInstance
->GetYieldMutex();
660 ::vos::OGuard
aGuard( *pSalInstYieldMutex
);
665 SalX11Display::SalX11Display( Display
*display
)
666 : SalDisplay( display
)
670 pXLib_
->Insert( ConnectionNumber( pDisp_
),
672 (YieldFunc
) DisplayHasEvent
,
673 (YieldFunc
) DisplayQueue
,
674 (YieldFunc
) DisplayYield
);
677 SalX11Display::~SalX11Display()
679 #if OSL_DEBUG_LEVEL > 1
680 fprintf( stderr
, "SalX11Display::~SalX11Display()\n" );
685 XCloseDisplay( pDisp_
);
690 void SalDisplay::initScreen( int nScreen
) const
692 if( nScreen
< 0 || nScreen
>= static_cast<int>(m_aScreens
.size()) )
693 nScreen
= m_nDefaultScreen
;
694 ScreenData
& rSD
= const_cast<ScreenData
&>(m_aScreens
[nScreen
]);
702 if( SalDisplay::BestVisual( pDisp_
, nScreen
, aVI
) ) // DefaultVisual
703 aColMap
= DefaultColormap( pDisp_
, nScreen
);
705 aColMap
= XCreateColormap( pDisp_
,
706 RootWindow( pDisp_
, nScreen
),
710 Screen
* pScreen
= ScreenOfDisplay( pDisp_
, nScreen
);
712 rSD
.m_aSize
= Size( WidthOfScreen( pScreen
), HeightOfScreen( pScreen
) );
713 rSD
.m_aRoot
= RootWindow( pDisp_
, nScreen
);
714 rSD
.m_aVisual
= SalVisual( &aVI
);
715 rSD
.m_aColormap
= SalColormap( this, aColMap
, nScreen
);
717 // we're interested in configure notification of root windows
718 InitRandR( rSD
.m_aRoot
);
720 // - - - - - - - - - - Reference Window/Default Drawable - -
721 XSetWindowAttributes aXWAttributes
;
722 aXWAttributes
.border_pixel
= 0;
723 aXWAttributes
.background_pixel
= 0;
724 aXWAttributes
.colormap
= aColMap
;
725 rSD
.m_aRefWindow
= XCreateWindow( pDisp_
,
728 rSD
.m_aVisual
.GetDepth(),
730 rSD
.m_aVisual
.GetVisual(),
731 CWBorderPixel
|CWBackPixel
|CWColormap
,
734 // set client leader (session id gets set when session is started)
735 if( rSD
.m_aRefWindow
)
737 // client leader must have WM_CLIENT_LEADER pointing to itself
738 XChangeProperty( pDisp_
,
740 XInternAtom( pDisp_
, "WM_CLIENT_LEADER", False
),
744 (unsigned char*)&rSD
.m_aRefWindow
,
748 ByteString
aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
751 argv
[1] = aExec
.GetBuffer();
752 XSetCommand( pDisp_
, rSD
.m_aRefWindow
, const_cast<char**>(argv
), 2 );
753 XSelectInput( pDisp_
, rSD
.m_aRefWindow
, PropertyChangeMask
);
755 // - - - - - - - - - - GCs - - - - - - - - - - - - - - - - -
757 values
.graphics_exposures
= False
;
758 values
.fill_style
= FillOpaqueStippled
;
759 values
.background
= (1<<rSD
.m_aVisual
.GetDepth())-1;
760 values
.foreground
= 0;
762 rSD
.m_aCopyGC
= XCreateGC( pDisp_
,
768 rSD
.m_aAndInvertedGC
= XCreateGC( pDisp_
,
774 rSD
.m_aAndGC
= XCreateGC( pDisp_
,
780 rSD
.m_aOrGC
= XCreateGC( pDisp_
,
786 rSD
.m_aStippleGC
= XCreateGC( pDisp_
,
794 XSetFunction( pDisp_
, rSD
.m_aAndInvertedGC
, GXandInverted
);
795 XSetFunction( pDisp_
, rSD
.m_aAndGC
, GXand
);
796 // #44556# PowerPC Solaris 2.5 (XSun 3500) Bug: GXor = GXnop
797 //XSetFunction( pDisp_, pOrGC_, GXor );
798 XSetFunction( pDisp_
, rSD
.m_aOrGC
, GXxor
);
800 if( 1 == rSD
.m_aVisual
.GetDepth() )
802 XSetFunction( pDisp_
, rSD
.m_aCopyGC
, GXcopyInverted
);
803 rSD
.m_aMonoGC
= rSD
.m_aCopyGC
;
807 Pixmap hPixmap
= XCreatePixmap( pDisp_
, rSD
.m_aRefWindow
, 1, 1, 1 );
808 rSD
.m_aMonoGC
= XCreateGC( pDisp_
,
812 XFreePixmap( pDisp_
, hPixmap
);
814 rSD
.m_hInvert50
= XCreateBitmapFromData( pDisp_
,
822 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
823 void SalDisplay::Init()
825 for( size_t i
= 0; i
< POINTER_COUNT
; i
++ )
826 aPointerCache_
[i
] = None
;
828 eWindowManager_
= otherwm
;
829 nProperties_
= PROPERTY_DEFAULT
;
832 mpFontList
= (XlfdStorage
*)NULL
;
833 mpFactory
= (AttributeProvider
*)NULL
;
837 int nDisplayScreens
= ScreenCount( pDisp_
);
838 m_aScreens
= std::vector
<ScreenData
>(nDisplayScreens
);
840 mbExactResolution
= false;
842 * Xft resolution should take precedence since
843 * it is what modern desktops use.
845 const char* pValStr
= XGetDefault( pDisp_
, "Xft", "dpi" );
846 if( pValStr
!= NULL
)
848 const rtl::OString
aValStr( pValStr
);
849 const long nDPI
= (long) aValStr
.toDouble();
850 // guard against insane resolution
851 if( (nDPI
>= 50) && (nDPI
<= 500) )
853 aResolution_
= Pair( nDPI
, nDPI
);
854 mbExactResolution
= true;
857 if( mbExactResolution
== false )
860 Pair( DPI( WidthOfScreen( DefaultScreenOfDisplay( pDisp_
) ), DisplayWidthMM ( pDisp_
, m_nDefaultScreen
) ),
861 DPI( HeightOfScreen( DefaultScreenOfDisplay( pDisp_
) ), DisplayHeightMM( pDisp_
, m_nDefaultScreen
) ) );
864 nMaxRequestSize_
= XExtendedMaxRequestSize( pDisp_
) * 4;
865 if( !nMaxRequestSize_
)
866 nMaxRequestSize_
= XMaxRequestSize( pDisp_
) * 4;
869 X11SalBitmap::ImplCreateCache();
871 hEventGuard_
= osl_createMutex();
872 bLocal_
= FALSE
; /* dont care, initialize later by
873 calling SalDisplay::IsLocal() */
874 mbLocalIsValid
= FALSE
; /* bLocal_ is not yet initialized */
876 // - - - - - - - - - - Synchronize - - - - - - - - - - - - -
877 if( getenv( "SAL_SYNCHRONIZE" ) )
878 XSynchronize( pDisp_
, True
);
880 // - - - - - - - - - - Keyboardmapping - - - - - - - - - - -
883 // - - - - - - - - - - Window Manager - - - - - - - - - - -
884 m_pWMAdaptor
= ::vcl_sal::WMAdaptor::createWMAdaptor( this );
885 const char *pWM
= getenv( "SAL_WM" );
889 sscanf( pWM
, "%li", &nWM
);
890 eWindowManager_
= SalWM(nWM
);
892 else if( XInternAtom( pDisp_
, "_SGI_TELL_WM", True
) )
893 eWindowManager_
= FourDwm
;
894 else if( XInternAtom( pDisp_
, "KWM_RUNNING", True
) )
895 eWindowManager_
= mwm
; // naja, eigentlich kwm ...
896 else if( XInternAtom( pDisp_
, "_OL_WIN_ATTR", True
) )
897 eWindowManager_
= olwm
;
898 else if( m_pWMAdaptor
->getWindowManagerName().EqualsAscii( "Dtwm" ) )
899 eWindowManager_
= dtwm
;
901 // - - - - - - - - - - Properties - - - - - - - - - - - - -
902 const char *pProperties
= getenv( "SAL_PROPERTIES" );
904 sscanf( pProperties
, "%li", &nProperties_
);
907 #if defined DBG_UTIL || defined SUN || defined LINUX || defined FREEBSD || defined IRIX
908 nProperties_
|= PROPERTY_FEATURE_Maximize
;
910 // Server Bugs & Properties
911 if( GetServerVendor() == vendor_excursion
)
913 nProperties_
|= PROPERTY_BUG_Stipple
;
914 nProperties_
|= PROPERTY_BUG_DrawLine
;
915 nProperties_
&= ~PROPERTY_SUPPORT_XSetClipMask
;
918 if( GetServerVendor() == vendor_attachmate
)
920 nProperties_
|= PROPERTY_BUG_CopyPlane_RevertBWPixel
;
923 if( GetServerVendor() == vendor_ibm
)
925 nProperties_
|= PROPERTY_BUG_XA_FAMILY_NAME_nil
;
927 if( otherwm
== eWindowManager_
) eWindowManager_
= mwm
;
930 if( GetServerVendor() == vendor_xfree
)
932 nProperties_
|= PROPERTY_BUG_XCopyArea_GXxor
;
933 #if defined LINUX || defined FREEBSD
934 // otherwm and olwm are a kind of default, which are not detected
935 // carefully. if we are running linux (i.e. not netbsd) on an xfree
936 // display, fvwm is most probable the wm to choose, confusing with mwm
937 // doesn't harm. #57791# start maximized if possible
938 if( (otherwm
== eWindowManager_
)
939 || (olwm
== eWindowManager_
))
941 eWindowManager_
= fvwm
; // ???
942 nProperties_
|= PROPERTY_FEATURE_Maximize
;
945 if( otherwm
== eWindowManager_
) eWindowManager_
= winmgr
;
947 #if defined SOLARIS && defined SPARC
948 nProperties_
|= PROPERTY_BUG_Bitmap_Bit_Order
;
949 // solaris xlib seems to have problems with putting images
950 // in correct bit order to xfree 8 bit displays
954 if( GetServerVendor() == vendor_sun
)
956 // nicht alle! (bekannt: nur Sparc II CG3, CG6?)
957 nProperties_
&= ~PROPERTY_SUPPORT_XSetClipMask
;
959 // trusted solaris doesn't allow to change properties on the
960 // wm decoration window
961 if (sal_IsTrustedSolaris (pDisp_
))
962 nProperties_
|= PROPERTY_FEATURE_TrustedSolaris
;
964 // Fehler im Sun-Solaris X86 Server !
965 if (ImageByteOrder(GetDisplay()) == LSBFirst
)
967 nProperties_
|= PROPERTY_BUG_Tile
;
968 nProperties_
|= PROPERTY_SUPPORT_3ButtonMouse
;
970 else // MSBFirst Sun-Solaris Sparc Server
972 // XCopyPlane reverts black and white for 1bit bitmaps
973 // only sun, only 8bit pseudocolor target
974 if ( (GetVisual(m_nDefaultScreen
).GetDepth() == 8)
975 && (GetVisual(m_nDefaultScreen
).GetClass() == PseudoColor
))
976 nProperties_
|= PROPERTY_BUG_CopyPlane_RevertBWPixel
;
977 // Fehler in Solaris 2.5.1
978 if (VendorRelease ( GetDisplay() ) < 3600)
979 nProperties_
|= PROPERTY_BUG_FillPolygon_Tile
;
982 if( otherwm
== eWindowManager_
)
983 eWindowManager_
= olwm
;
986 if( GetServerVendor() == vendor_sco
)
988 if( otherwm
== eWindowManager_
) eWindowManager_
= pmwm
;
991 if( GetServerVendor() == vendor_sgi
)
993 if( GetVisual( m_nDefaultScreen
).GetDepth() > 8 && GetVisual( m_nDefaultScreen
).GetDepth() <= 16 )
994 nProperties_
|= PROPERTY_BUG_XCopyArea_GXxor
;
995 nProperties_
|= PROPERTY_SUPPORT_XSetClipMask
;
997 if( otherwm
== eWindowManager_
)
998 eWindowManager_
= FourDwm
;
1001 if( GetServerVendor() == vendor_hp
)
1003 if( otherwm
== eWindowManager_
) eWindowManager_
= dtwm
;
1006 if( GetServerVendor() == vendor_hummingbird
)
1008 if (GetVisual(m_nDefaultScreen
).GetDepth() == 24)
1009 nProperties_
|= PROPERTY_BUG_CopyArea_OnlySmallSlices
;
1012 if( otherwm
== eWindowManager_
)
1014 if( !XInternAtom( pDisp_
, "_MOTIF_WM_INFO", True
) )
1015 eWindowManager_
= olwm
;
1019 if( winmgr
== eWindowManager_
)
1021 nProperties_
&= ~PROPERTY_SUPPORT_WM_SetPos
;
1022 nProperties_
&= ~PROPERTY_SUPPORT_WM_Screen
;
1023 nProperties_
|= PROPERTY_FEATURE_Maximize
;
1025 else if( dtwm
== eWindowManager_
)
1027 nProperties_
&= ~PROPERTY_SUPPORT_WM_ClientPos
;
1029 else if( pmwm
== eWindowManager_
)
1031 nProperties_
&= ~PROPERTY_SUPPORT_WM_ClientPos
;
1037 // initialize system settings update
1038 m_pDtIntegrator
= DtIntegrator::CreateDtIntegrator();
1046 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1047 void SalDisplay::Beep() const
1053 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1055 void SalDisplay::SimulateKeyPress( USHORT nKeyCode
)
1057 #if __XTestExtension__
1058 if (nKeyCode
== KEY_CAPSLOCK
)
1060 XLIB_KeyCode keyCaps
= XKeysymToKeycode(GetDisplay(), XK_Caps_Lock
);
1061 if (XTestFakeKeyEvent(GetDisplay(), keyCaps
, true, CurrentTime
))
1062 XTestFakeKeyEvent(GetDisplay(), keyCaps
, false, CurrentTime
);
1067 USHORT
SalDisplay::GetIndicatorState() const
1069 unsigned int _state
= 0;
1071 XkbGetIndicatorState(pDisp_
, XkbUseCoreKbd
, &_state
);
1073 if ((_state
& 0x00000001))
1074 nState
|= INDICATOR_CAPSLOCK
;
1075 if ((_state
& 0x00000002))
1076 nState
|= INDICATOR_NUMLOCK
;
1077 if ((_state
& 0x00000004))
1078 nState
|= INDICATOR_SCROLLLOCK
;
1083 String
SalDisplay::GetKeyNameFromKeySym( KeySym nKeySym
) const
1087 // return an empty string for keysyms that are not bound to
1089 XLIB_KeyCode aKeyCode
= XKeysymToKeycode( GetDisplay(), nKeySym
);
1090 if( aKeyCode
!= 0 && aKeyCode
!= NoSymbol
)
1093 aRet
= String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "???" ) );
1096 aRet
= ::vcl_sal::getKeysymReplacementName( const_cast<SalDisplay
*>(this)->GetKeyboardName(), nKeySym
);
1099 const char *pString
= XKeysymToString( nKeySym
);
1100 int n
= strlen( pString
);
1101 if( n
> 2 && pString
[n
-2] == '_' )
1102 aRet
= String( pString
, n
-2, RTL_TEXTENCODING_ISO_8859_1
);
1104 aRet
= String( pString
, n
, RTL_TEXTENCODING_ISO_8859_1
);
1111 inline KeySym
sal_XModifier2Keysym( Display
*pDisplay
,
1112 XModifierKeymap
*pXModMap
,
1115 return XKeycodeToKeysym( pDisplay
,
1116 pXModMap
->modifiermap
[n
*pXModMap
->max_keypermod
],
1120 void SalDisplay::ModifierMapping()
1122 XModifierKeymap
*pXModMap
= XGetModifierMapping( pDisp_
);
1124 bNumLockFromXS_
= True
;
1125 nShiftKeySym_
= sal_XModifier2Keysym( pDisp_
, pXModMap
, ShiftMapIndex
);
1126 nCtrlKeySym_
= sal_XModifier2Keysym( pDisp_
, pXModMap
, ControlMapIndex
);
1127 nMod1KeySym_
= sal_XModifier2Keysym( pDisp_
, pXModMap
, Mod1MapIndex
);
1128 // Auf Sun-Servern und SCO-Severn beruecksichtigt XLookupString
1129 // nicht den NumLock Modifier.
1130 if( (GetServerVendor() == vendor_sun
)
1131 || (GetServerVendor() == vendor_sco
) )
1133 XLIB_KeyCode aNumLock
= XKeysymToKeycode( pDisp_
, XK_Num_Lock
);
1135 if( aNumLock
) for( int i
= ShiftMapIndex
; i
<= Mod5MapIndex
; i
++ )
1137 if( pXModMap
->modifiermap
[i
*pXModMap
->max_keypermod
] == aNumLock
)
1139 bNumLockFromXS_
= False
;
1141 nNumLockMask_
= 1<<i
;
1147 XFreeModifiermap( pXModMap
);
1150 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1151 XubString
SalDisplay::GetKeyName( USHORT nKeyCode
) const
1155 if( nKeyCode
& KEY_MOD1
)
1156 aStrMap
+= GetKeyNameFromKeySym( nCtrlKeySym_
);
1158 if( nKeyCode
& KEY_MOD2
)
1162 aStrMap
+= GetKeyNameFromKeySym( nMod1KeySym_
);
1165 if( nKeyCode
& KEY_SHIFT
)
1169 aStrMap
+= GetKeyNameFromKeySym( nShiftKeySym_
);
1175 if( KEY_0
<= nKeyCode
&& nKeyCode
<= KEY_9
)
1176 nKeySym
= XK_0
+ (nKeyCode
- KEY_0
);
1177 else if( KEY_A
<= nKeyCode
&& nKeyCode
<= KEY_Z
)
1178 nKeySym
= XK_A
+ (nKeyCode
- KEY_A
);
1179 else if( KEY_F1
<= nKeyCode
&& nKeyCode
<= KEY_F26
) // Existiert die Taste
1180 nKeySym
= XK_F1
+ (nKeyCode
- KEY_F1
);
1181 else switch( nKeyCode
)
1208 nKeySym
= XK_Return
;
1211 nKeySym
= XK_Escape
;
1217 nKeySym
= XK_BackSpace
;
1223 nKeySym
= XK_Insert
;
1226 nKeySym
= XK_Delete
;
1229 #if !defined (SunXK_Undo)
1230 #define SunXK_Stop 0x0000FF69 // XK_Cancel
1231 #define SunXK_Props 0x1005FF70
1232 #define SunXK_Front 0x1005FF71
1233 #define SunXK_Copy 0x1005FF72
1234 #define SunXK_Open 0x1005FF73
1235 #define SunXK_Paste 0x1005FF74
1236 #define SunXK_Cut 0x1005FF75
1242 case KEY_PROPERTIES
:
1243 nKeySym
= SunXK_Props
;
1249 nKeySym
= SunXK_Front
;
1252 nKeySym
= SunXK_Copy
;
1255 nKeySym
= SunXK_Open
;
1258 nKeySym
= SunXK_Paste
;
1264 nKeySym
= GetServerVendor() == vendor_sun
? SunXK_Cut
: XK_L10
;
1273 nKeySym
= XK_asterisk
;
1279 nKeySym
= XK_period
;
1288 nKeySym
= XK_greater
;
1296 case KEY_HANGUL_HANJA
:
1297 nKeySym
= XK_Hangul_Hanja
;
1300 nKeySym
= XK_asciitilde
;
1305 case KEY_BRACKETLEFT
:
1306 nKeySym
= XK_bracketleft
;
1308 case KEY_BRACKETRIGHT
:
1309 nKeySym
= XK_bracketright
;
1319 String aKeyName
= GetKeyNameFromKeySym( nKeySym
);
1320 if( aKeyName
.Len() )
1324 aStrMap
+= aKeyName
;
1335 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1337 #define IsISOKey( n ) (0x0000FE00==((n)&0xFFFFFF00))
1340 USHORT
SalDisplay::GetKeyCode( KeySym keysym
, char*pcPrintable
) const
1344 if( XK_a
<= keysym
&& XK_z
>= keysym
)
1345 nKey
= (USHORT
)(KEY_A
+ (keysym
- XK_a
));
1346 else if( XK_A
<= keysym
&& XK_Z
>= keysym
)
1347 nKey
= (USHORT
)(KEY_A
+ (keysym
- XK_A
));
1348 else if( XK_0
<= keysym
&& XK_9
>= keysym
)
1349 nKey
= (USHORT
)(KEY_0
+ (keysym
- XK_0
));
1350 else if( IsModifierKey( keysym
) )
1352 else if( IsKeypadKey( keysym
) )
1354 if( (keysym
>= XK_KP_0
) && (keysym
<= XK_KP_9
) )
1356 nKey
= (USHORT
)(KEY_0
+ (keysym
- XK_KP_0
));
1357 *pcPrintable
= '0' + nKey
- KEY_0
;
1359 else if( IsPFKey( keysym
) )
1360 nKey
= (USHORT
)(KEY_F1
+ (keysym
- XK_KP_F1
));
1361 else switch( keysym
)
1389 case XK_KP_Prior
: // XK_KP_Page_Up
1392 case XK_KP_Next
: // XK_KP_Page_Down
1393 nKey
= KEY_PAGEDOWN
;
1408 case XK_KP_Multiply
:
1409 nKey
= KEY_MULTIPLY
;
1416 case XK_KP_Separator
:
1420 case XK_KP_Subtract
:
1421 nKey
= KEY_SUBTRACT
;
1434 else if( IsFunctionKey( keysym
) )
1436 if( bNumLockFromXS_
)
1438 if( keysym
>= XK_F1
&& keysym
<= XK_F26
)
1439 nKey
= (USHORT
)(KEY_F1
+ keysym
- XK_F1
);
1441 else switch( keysym
)
1443 // - - - - - Sun X-Server Tastatur ohne Cursorblock ??? - - -
1444 case XK_R7
: // XK_F27:
1447 case XK_R8
: // XK_F28:
1450 case XK_R9
: // XK_F29:
1453 case XK_R10
: // XK_F30:
1456 case XK_R11
: // XK_F31:
1457 nKey
= 0; // KEY_F31
1459 case XK_R12
: // XK_F32:
1462 case XK_R13
: // XK_F33:
1465 case XK_R14
: // XK_F34:
1468 case XK_R15
: // XK_F35:
1469 nKey
= KEY_PAGEDOWN
;
1471 // - - - - - Sun X-Server Tastatur ??? - - - - - - - - - - - -
1472 case XK_L1
: // XK_F11:
1473 nKey
= KEY_F11
; // on a sun keyboard this actually is usally SunXK_Stop,
1474 // but VCL doesn't have a key defintion for that
1476 case XK_L2
: // XK_F12:
1477 if ( GetServerVendor() == vendor_sun
)
1482 case XK_L3
: // XK_F13:
1483 nKey
= KEY_PROPERTIES
; // KEY_F13
1485 case XK_L4
: // XK_F14:
1486 nKey
= KEY_UNDO
; // KEY_F14
1488 case XK_L5
: // XK_F15:
1489 nKey
= KEY_F15
; // KEY_FRONT
1491 case XK_L6
: // XK_F16:
1492 nKey
= KEY_COPY
; // KEY_F16
1494 case XK_L7
: // XK_F17:
1495 nKey
= KEY_F17
; // KEY_OPEN
1497 case XK_L8
: // XK_F18:
1498 nKey
= KEY_PASTE
; // KEY_F18
1500 case XK_L9
: // XK_F19:
1501 nKey
= KEY_F19
; // KEY_FIND
1503 case XK_L10
: // XK_F20:
1504 nKey
= KEY_CUT
; // KEY_F20
1507 if( keysym
>= XK_F1
&& keysym
<= XK_F26
)
1508 nKey
= (USHORT
)(KEY_F1
+ keysym
- XK_F1
);
1512 else if( IsCursorKey( keysym
) )
1532 case XK_Prior
: // XK_Page_Up
1535 case XK_Next
: // XK_Page_Down
1536 nKey
= KEY_PAGEDOWN
;
1543 else if( IsMiscFunctionKey( keysym
) )
1563 nKey
= KEY_CONTEXTMENU
;
1574 else if( IsISOKey( keysym
) ) // XK_ISO_
1578 case 0xFE20: // XK_ISO_Left_Tab:
1583 else switch( keysym
)
1589 nKey
= KEY_BACKSPACE
;
1607 nKey
= KEY_SUBTRACT
;
1610 nKey
= KEY_MULTIPLY
;
1630 case XK_Hangul_Hanja
:
1631 nKey
= KEY_HANGUL_HANJA
;
1638 nKey
= KEY_QUOTELEFT
;
1641 case XK_bracketleft
:
1642 nKey
= KEY_BRACKETLEFT
;
1645 case XK_bracketright
:
1646 nKey
= KEY_BRACKETRIGHT
;
1649 // case XK_Linefeed:
1650 // *pcPrintable = '\n';
1652 // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000
1653 case 0x1000FF02: // apXK_Copy
1656 case 0x1000FF03: // apXK_Cut
1659 case 0x1000FF04: // apXK_Paste
1662 case 0x1000FF14: // apXK_Repeat
1666 // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000
1670 // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000
1671 case 0x1000FF73: // hpXK_DeleteChar
1674 case 0x1000FF74: // hpXK_BackTab
1675 case 0x1000FF75: // hpXK_KP_BackTab
1678 // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - -
1679 // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004
1680 case 0x1004FF02: // osfXK_Copy
1683 case 0x1004FF03: // osfXK_Cut
1686 case 0x1004FF04: // osfXK_Paste
1689 case 0x1004FF07: // osfXK_BackTab
1692 case 0x1004FF08: // osfXK_BackSpace
1693 nKey
= KEY_BACKSPACE
;
1695 case 0x1004FF1B: // osfXK_Escape
1698 // Up, Down, Left, Right, PageUp, PageDown
1699 // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - -
1700 // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007
1701 // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - -
1702 // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005
1703 case 0x1005FF10: // SunXK_F36
1706 case 0x1005FF11: // SunXK_F37
1709 case 0x1005FF70: // SunXK_Props
1710 nKey
= KEY_PROPERTIES
;
1712 case 0x1005FF71: // SunXK_Front
1715 case 0x1005FF72: // SunXK_Copy
1718 case 0x1005FF73: // SunXK_Open
1721 case 0x1005FF74: // SunXK_Paste
1724 case 0x1005FF75: // SunXK_Cut
1731 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1732 KeySym
SalDisplay::GetKeySym( XKeyEvent
*pEvent
,
1733 unsigned char *pPrintable
,
1735 KeySym
*pUnmodifiedKeySym
,
1736 Status
*pStatusReturn
,
1737 XIC aInputContext
) const
1740 memset( pPrintable
, 0, *pLen
);
1743 // first get the printable of the possibly modified KeySym
1744 if ( (aInputContext
== 0)
1745 || (pEvent
->type
== KeyRelease
)
1746 || (mpInputMethod
!= NULL
&& mpInputMethod
->PosixLocale()) )
1748 // XmbLookupString must not be called for KeyRelease events
1749 // Cannot enter space in c locale problem #89616# #88978# btraq #4478197
1750 *pLen
= XLookupString( pEvent
, (char*)pPrintable
, 1, &nKeySym
, NULL
);
1754 *pLen
= XmbLookupString( aInputContext
,
1755 pEvent
, (char*)pPrintable
, *pLen
- 1, &nKeySym
, pStatusReturn
);
1757 // Lookup the string again, now with appropriate size
1758 if ( *pStatusReturn
== XBufferOverflow
)
1760 pPrintable
[ 0 ] = (char)0;
1764 switch ( *pStatusReturn
)
1766 case XBufferOverflow
:
1767 /* unhandled error */
1770 /* unhandled error */
1773 /* #72223# this is a strange one: on exceed sometimes
1774 * no printable is returned for the first char entered,
1775 * just to retry lookup solves the problem. The problem
1776 * is not yet fully understood, so restrict 2nd lookup
1777 * to 7bit ascii chars */
1778 if ( (XK_space
<= nKeySym
) && (XK_asciitilde
>= nKeySym
) )
1781 pPrintable
[ 0 ] = (char)nKeySym
;
1787 /* nothing to, char allready in pPrintable */
1792 if( !bNumLockFromXS_
1793 && (IsCursorKey(nKeySym
)
1794 || IsFunctionKey(nKeySym
)
1795 || IsKeypadKey(nKeySym
)
1796 || XK_Delete
== nKeySym
) )
1798 // Bei einigen X-Servern muss man bei den Keypadtasten
1799 // schon sehr genau hinschauen. ZB. Solaris XServer:
1800 // 2, 4, 6, 8 werden als Cursorkeys klassifiziert (Up, Down, Left, Right
1801 // 1, 3, 5, 9 werden als Functionkeys klassifiziert (F27,F29,F33,F35)
1802 // 0 als Keypadkey und der Dezimalpunkt gar nicht (KP_Insert)
1803 KeySym nNewKeySym
= XLookupKeysym( pEvent
, nNumLockIndex_
);
1804 if( nNewKeySym
!= NoSymbol
)
1805 nKeySym
= nNewKeySym
;
1808 // Now get the unmodified KeySym for KeyCode retrieval
1809 // try to strip off modifiers, e.g. Ctrl-$ becomes Ctrl-Shift-4
1810 *pUnmodifiedKeySym
= XKeycodeToKeysym( GetDisplay(), pEvent
->keycode
, 0);
1816 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1817 #define MAKE_BITMAP( name ) \
1818 XCreateBitmapFromData( pDisp_, \
1819 DefaultRootWindow( pDisp_ ), \
1824 #define MAKE_CURSOR( name ) \
1825 aCursBitmap = MAKE_BITMAP( name##curs ); \
1826 aMaskBitmap = MAKE_BITMAP( name##mask ); \
1827 nXHot = name##curs_x_hot; \
1828 nYHot = name##curs_y_hot
1830 XLIB_Cursor
SalDisplay::GetPointer( int ePointerStyle
)
1832 if( ePointerStyle
>= POINTER_COUNT
)
1835 XLIB_Cursor
&aCur
= aPointerCache_
[ePointerStyle
];
1840 Pixmap aCursBitmap
= None
, aMaskBitmap
= None
;
1841 unsigned int nXHot
= 0, nYHot
= 0;
1843 switch( ePointerStyle
)
1846 MAKE_CURSOR( null
);
1849 aCur
= XCreateFontCursor( pDisp_
, XC_left_ptr
);
1850 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1853 aCur
= XCreateFontCursor( pDisp_
, XC_watch
);
1855 case POINTER_TEXT
: // Mouse Pointer ist ein "I" Beam
1856 aCur
= XCreateFontCursor( pDisp_
, XC_xterm
);
1857 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1860 aCur
= XCreateFontCursor( pDisp_
, XC_question_arrow
);
1861 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1863 case POINTER_CROSS
: // Mouse Pointer ist ein Kreuz
1864 aCur
= XCreateFontCursor( pDisp_
, XC_crosshair
);
1865 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1868 aCur
= XCreateFontCursor( pDisp_
, XC_sb_v_double_arrow
);
1869 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1872 aCur
= XCreateFontCursor( pDisp_
, XC_sb_v_double_arrow
);
1873 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1876 aCur
= XCreateFontCursor( pDisp_
, XC_sb_h_double_arrow
);
1877 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1880 aCur
= XCreateFontCursor( pDisp_
, XC_sb_h_double_arrow
);
1881 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1883 case POINTER_WINDOW_NSIZE
:
1884 aCur
= XCreateFontCursor( pDisp_
, XC_top_side
);
1885 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1887 case POINTER_WINDOW_SSIZE
:
1888 aCur
= XCreateFontCursor( pDisp_
, XC_bottom_side
);
1889 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1891 case POINTER_WINDOW_WSIZE
:
1892 aCur
= XCreateFontCursor( pDisp_
, XC_left_side
);
1893 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1895 case POINTER_WINDOW_ESIZE
:
1896 aCur
= XCreateFontCursor( pDisp_
, XC_right_side
);
1897 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1899 case POINTER_NWSIZE
:
1900 aCur
= XCreateFontCursor( pDisp_
, XC_top_left_corner
);
1902 case POINTER_NESIZE
:
1903 aCur
= XCreateFontCursor( pDisp_
, XC_top_right_corner
);
1905 case POINTER_SWSIZE
:
1906 aCur
= XCreateFontCursor( pDisp_
, XC_bottom_left_corner
);
1908 case POINTER_SESIZE
:
1909 aCur
= XCreateFontCursor( pDisp_
, XC_bottom_right_corner
);
1911 case POINTER_WINDOW_NWSIZE
:
1912 aCur
= XCreateFontCursor( pDisp_
, XC_top_left_corner
);
1913 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1915 case POINTER_WINDOW_NESIZE
:
1916 aCur
= XCreateFontCursor( pDisp_
, XC_top_right_corner
);
1917 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1919 case POINTER_WINDOW_SWSIZE
:
1920 aCur
= XCreateFontCursor( pDisp_
, XC_bottom_left_corner
);
1921 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1923 case POINTER_WINDOW_SESIZE
:
1924 aCur
= XCreateFontCursor( pDisp_
, XC_bottom_right_corner
);
1925 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1927 case POINTER_HSPLIT
:
1928 aCur
= XCreateFontCursor( pDisp_
, XC_sb_h_double_arrow
);
1930 case POINTER_VSPLIT
:
1931 aCur
= XCreateFontCursor( pDisp_
, XC_sb_v_double_arrow
);
1933 case POINTER_HSIZEBAR
:
1934 aCur
= XCreateFontCursor( pDisp_
, XC_sb_h_double_arrow
); // ???
1935 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1937 case POINTER_VSIZEBAR
:
1938 aCur
= XCreateFontCursor( pDisp_
, XC_sb_v_double_arrow
); // ???
1939 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1941 case POINTER_REFHAND
:
1942 aCur
= XCreateFontCursor( pDisp_
, XC_hand1
);
1943 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
1946 aCur
= XCreateFontCursor( pDisp_
, XC_hand2
);
1948 case POINTER_MAGNIFY
:
1949 MAKE_CURSOR( magnify_
);
1952 MAKE_CURSOR( fill_
);
1955 aCur
= XCreateFontCursor( pDisp_
, XC_fleur
);
1957 case POINTER_MOVEDATA
:
1958 MAKE_CURSOR( movedata_
);
1960 case POINTER_COPYDATA
:
1961 MAKE_CURSOR( copydata_
);
1963 case POINTER_MOVEFILE
:
1964 MAKE_CURSOR( movefile_
);
1966 case POINTER_COPYFILE
:
1967 MAKE_CURSOR( copyfile_
);
1969 case POINTER_MOVEFILES
:
1970 MAKE_CURSOR( movefiles_
);
1972 case POINTER_COPYFILES
:
1973 MAKE_CURSOR( copyfiles_
);
1975 case POINTER_NOTALLOWED
:
1976 MAKE_CURSOR( nodrop_
);
1978 case POINTER_ROTATE
:
1979 MAKE_CURSOR( rotate_
);
1981 case POINTER_HSHEAR
:
1982 MAKE_CURSOR( hshear_
);
1984 case POINTER_VSHEAR
:
1985 MAKE_CURSOR( vshear_
);
1987 case POINTER_DRAW_LINE
:
1988 MAKE_CURSOR( drawline_
);
1990 case POINTER_DRAW_RECT
:
1991 MAKE_CURSOR( drawrect_
);
1993 case POINTER_DRAW_POLYGON
:
1994 MAKE_CURSOR( drawpolygon_
);
1996 case POINTER_DRAW_BEZIER
:
1997 MAKE_CURSOR( drawbezier_
);
1999 case POINTER_DRAW_ARC
:
2000 MAKE_CURSOR( drawarc_
);
2002 case POINTER_DRAW_PIE
:
2003 MAKE_CURSOR( drawpie_
);
2005 case POINTER_DRAW_CIRCLECUT
:
2006 MAKE_CURSOR( drawcirclecut_
);
2008 case POINTER_DRAW_ELLIPSE
:
2009 MAKE_CURSOR( drawellipse_
);
2011 case POINTER_DRAW_CONNECT
:
2012 MAKE_CURSOR( drawconnect_
);
2014 case POINTER_DRAW_TEXT
:
2015 MAKE_CURSOR( drawtext_
);
2017 case POINTER_MIRROR
:
2018 MAKE_CURSOR( mirror_
);
2021 MAKE_CURSOR( crook_
);
2024 MAKE_CURSOR( crop_
);
2026 case POINTER_MOVEPOINT
:
2027 MAKE_CURSOR( movepoint_
);
2029 case POINTER_MOVEBEZIERWEIGHT
:
2030 MAKE_CURSOR( movebezierweight_
);
2032 case POINTER_DRAW_FREEHAND
:
2033 MAKE_CURSOR( drawfreehand_
);
2035 case POINTER_DRAW_CAPTION
:
2036 MAKE_CURSOR( drawcaption_
);
2038 case POINTER_PEN
: // Mouse Pointer ist ein Stift
2039 aCur
= XCreateFontCursor( pDisp_
, XC_pencil
);
2040 DBG_ASSERT( aCur
!= None
, "GetPointer: Could not define cursor" );
2042 case POINTER_LINKDATA
:
2043 MAKE_CURSOR( linkdata_
);
2045 case POINTER_MOVEDATALINK
:
2046 MAKE_CURSOR( movedlnk_
);
2048 case POINTER_COPYDATALINK
:
2049 MAKE_CURSOR( copydlnk_
);
2051 case POINTER_LINKFILE
:
2052 MAKE_CURSOR( linkfile_
);
2054 case POINTER_MOVEFILELINK
:
2055 MAKE_CURSOR( moveflnk_
);
2057 case POINTER_COPYFILELINK
:
2058 MAKE_CURSOR( copyflnk_
);
2061 MAKE_CURSOR( chart_
);
2063 case POINTER_DETECTIVE
:
2064 MAKE_CURSOR( detective_
);
2066 case POINTER_PIVOT_COL
:
2067 MAKE_CURSOR( pivotcol_
);
2069 case POINTER_PIVOT_ROW
:
2070 MAKE_CURSOR( pivotrow_
);
2072 case POINTER_PIVOT_FIELD
:
2073 MAKE_CURSOR( pivotfld_
);
2075 case POINTER_PIVOT_DELETE
:
2076 MAKE_CURSOR( pivotdel_
);
2079 MAKE_CURSOR( chain_
);
2081 case POINTER_CHAIN_NOTALLOWED
:
2082 MAKE_CURSOR( chainnot_
);
2084 case POINTER_TIMEEVENT_MOVE
:
2085 MAKE_CURSOR( timemove_
);
2087 case POINTER_TIMEEVENT_SIZE
:
2088 MAKE_CURSOR( timesize_
);
2090 case POINTER_AUTOSCROLL_N
:
2093 case POINTER_AUTOSCROLL_S
:
2094 MAKE_CURSOR( ass_
);
2096 case POINTER_AUTOSCROLL_W
:
2097 MAKE_CURSOR( asw_
);
2099 case POINTER_AUTOSCROLL_E
:
2100 MAKE_CURSOR( ase_
);
2102 case POINTER_AUTOSCROLL_NW
:
2103 MAKE_CURSOR( asnw_
);
2105 case POINTER_AUTOSCROLL_NE
:
2106 MAKE_CURSOR( asne_
);
2108 case POINTER_AUTOSCROLL_SW
:
2109 MAKE_CURSOR( assw_
);
2111 case POINTER_AUTOSCROLL_SE
:
2112 MAKE_CURSOR( asse_
);
2114 case POINTER_AUTOSCROLL_NS
:
2115 MAKE_CURSOR( asns_
);
2117 case POINTER_AUTOSCROLL_WE
:
2118 MAKE_CURSOR( aswe_
);
2120 case POINTER_AUTOSCROLL_NSWE
:
2121 MAKE_CURSOR( asnswe_
);
2123 case POINTER_AIRBRUSH
:
2124 MAKE_CURSOR( airbrush_
);
2126 case POINTER_TEXT_VERTICAL
:
2127 MAKE_CURSOR( vertcurs_
);
2130 // --> FME 2004-07-30 #i32329# Enhanced table selection
2131 case POINTER_TAB_SELECT_S
:
2132 MAKE_CURSOR( tblsels_
);
2134 case POINTER_TAB_SELECT_E
:
2135 MAKE_CURSOR( tblsele_
);
2137 case POINTER_TAB_SELECT_SE
:
2138 MAKE_CURSOR( tblselse_
);
2140 case POINTER_TAB_SELECT_W
:
2141 MAKE_CURSOR( tblselw_
);
2143 case POINTER_TAB_SELECT_SW
:
2144 MAKE_CURSOR( tblselsw_
);
2148 // --> FME 2004-08-16 #i20119# Paintbrush tool
2149 case POINTER_PAINTBRUSH
:
2150 MAKE_CURSOR( paintbrush_
);
2155 DBG_ERROR("pointer not implemented");
2156 aCur
= XCreateFontCursor( pDisp_
, XC_arrow
);
2162 XColor aBlack
, aWhite
, aDummy
;
2163 Colormap hColormap
= GetColormap(m_nDefaultScreen
).GetXColormap();
2165 XAllocNamedColor( pDisp_
, hColormap
, "black", &aBlack
, &aDummy
);
2166 XAllocNamedColor( pDisp_
, hColormap
, "white", &aWhite
, &aDummy
);
2168 aCur
= XCreatePixmapCursor( pDisp_
,
2169 aCursBitmap
, aMaskBitmap
,
2173 XFreePixmap( pDisp_
, aCursBitmap
);
2174 XFreePixmap( pDisp_
, aMaskBitmap
);
2180 int SalDisplay::CaptureMouse( SalFrame
*pCapture
)
2185 XUngrabPointer( GetDisplay(), CurrentTime
);
2186 XFlush( GetDisplay() );
2192 // FIXME: get rid of X11SalFrame
2193 const SystemEnvData
* pEnvData
= pCapture
->GetSystemData();
2194 int ret
= XGrabPointer( GetDisplay(),
2195 (XLIB_Window
)pEnvData
->aWindow
,
2197 PointerMotionMask
| ButtonPressMask
|ButtonReleaseMask
,
2201 static_cast<X11SalFrame
*>(pCapture
)->GetCursor(),
2204 if( ret
!= GrabSuccess
)
2206 DBG_ASSERT( 1, "SalDisplay::CaptureMouse could not grab pointer\n");
2210 m_pCapture
= pCapture
;
2215 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2217 void SalDisplay::SendInternalEvent( SalFrame
* pFrame
, void* pData
, USHORT nEvent
)
2219 if( osl_acquireMutex( hEventGuard_
) )
2221 m_aUserEvents
.push_back( SalUserEvent( pFrame
, pData
, nEvent
) );
2223 // Notify SalXLib::Yield() of a pending event.
2224 pXLib_
->PostUserEvent();
2226 osl_releaseMutex( hEventGuard_
);
2229 DBG_ASSERT( 1, "SalDisplay::SendInternalEvent !acquireMutex\n" );
2233 void SalDisplay::CancelInternalEvent( SalFrame
* pFrame
, void* pData
, USHORT nEvent
)
2235 if( osl_acquireMutex( hEventGuard_
) )
2237 if( ! m_aUserEvents
.empty() )
2239 std::list
< SalUserEvent
>::iterator it
, next
;
2240 next
= m_aUserEvents
.begin();
2244 if( it
->m_pFrame
== pFrame
&&
2245 it
->m_pData
== pData
&&
2246 it
->m_nEvent
== nEvent
)
2248 m_aUserEvents
.erase( it
);
2250 } while( next
!= m_aUserEvents
.end() );
2253 osl_releaseMutex( hEventGuard_
);
2256 DBG_ASSERT( 1, "SalDisplay::CancelInternalEvent !acquireMutex\n" );
2260 BOOL
SalX11Display::IsEvent()
2264 if( osl_acquireMutex( hEventGuard_
) )
2266 if( m_aUserEvents
.begin() != m_aUserEvents
.end() )
2268 osl_releaseMutex( hEventGuard_
);
2271 if( bRet
|| XEventsQueued( pDisp_
, QueuedAlready
) )
2278 bool SalDisplay::DispatchInternalEvent()
2280 SalFrame
* pFrame
= NULL
;
2284 if( osl_acquireMutex( hEventGuard_
) )
2286 if( m_aUserEvents
.begin() != m_aUserEvents
.end() )
2288 pFrame
= m_aUserEvents
.front().m_pFrame
;
2289 pData
= m_aUserEvents
.front().m_pData
;
2290 nEvent
= m_aUserEvents
.front().m_nEvent
;
2292 m_aUserEvents
.pop_front();
2294 osl_releaseMutex( hEventGuard_
);
2297 DBG_ASSERT( 1, "SalDisplay::Yield !acquireMutex\n" );
2301 pFrame
->CallCallback( nEvent
, pData
);
2303 return pFrame
!= NULL
;
2306 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2308 void SalX11Display::Yield()
2310 if( DispatchInternalEvent() )
2314 DBG_ASSERT( static_cast<SalYieldMutex
*>(GetSalData()->m_pInstance
->GetYieldMutex())->GetThreadId() ==
2315 NAMESPACE_VOS(OThread
)::getCurrentIdentifier(),
2316 "will crash soon since solar mutex not locked in SalDisplay::Yield" );
2318 XNextEvent( pDisp_
, &aEvent
);
2320 Dispatch( &aEvent
);
2323 if( pXLib_
->HasXErrorOccured() )
2326 PrintEvent( "SalDisplay::Yield (WasXError)", &aEvent
);
2329 pXLib_
->ResetXErrorOccured();
2332 long SalX11Display::Dispatch( XEvent
*pEvent
)
2334 if( pEvent
->type
== XLIB_KeyPress
|| pEvent
->type
== KeyRelease
)
2336 XLIB_Window aWindow
= pEvent
->xkey
.window
;
2338 std::list
< SalFrame
* >::const_iterator it
;
2339 for( it
= m_aFrames
.begin(); it
!= m_aFrames
.end(); ++it
)
2341 const X11SalFrame
* pFrame
= static_cast< const X11SalFrame
* >(*it
);
2342 if( pFrame
->GetWindow() == aWindow
|| pFrame
->GetShellWindow() == aWindow
)
2344 aWindow
= pFrame
->GetWindow();
2348 if( it
!= m_aFrames
.end() )
2350 if ( mpInputMethod
->FilterEvent( pEvent
, aWindow
) )
2355 if ( mpInputMethod
->FilterEvent( pEvent
, None
) )
2358 SalInstance
* pInstance
= GetSalData()->m_pInstance
;
2359 if( pInstance
->GetEventCallback() )
2361 YieldMutexReleaser aReleaser
;
2362 pInstance
->CallEventCallback( pEvent
, sizeof( XEvent
) );
2365 switch( pEvent
->type
)
2368 while( XCheckWindowEvent( pEvent
->xany
.display
,
2369 pEvent
->xany
.window
,
2373 m_nLastUserEventTime
= pEvent
->xmotion
.time
;
2375 case PropertyNotify
:
2376 if( pEvent
->xproperty
.atom
== getWMAdaptor()->getAtom( WMAdaptor::VCL_SYSTEM_SETTINGS
) )
2378 for( unsigned int i
= 0; i
< m_aScreens
.size(); i
++ )
2380 if( pEvent
->xproperty
.window
== m_aScreens
[i
].m_aRefWindow
)
2382 std::list
< SalFrame
* >::const_iterator it
;
2383 for( it
= m_aFrames
.begin(); it
!= m_aFrames
.end(); ++it
)
2384 (*it
)->CallCallback( SALEVENT_SETTINGSCHANGED
, NULL
);
2391 if( MappingKeyboard
== pEvent
->xmapping
.request
||
2392 MappingModifier
== pEvent
->xmapping
.request
)
2394 XRefreshKeyboardMapping( &pEvent
->xmapping
);
2395 if( MappingModifier
== pEvent
->xmapping
.request
)
2397 if( MappingKeyboard
== pEvent
->xmapping
.request
) // refresh mapping
2398 GetKeyboardName( TRUE
);
2403 m_nLastUserEventTime
= pEvent
->xbutton
.time
;
2407 m_nLastUserEventTime
= pEvent
->xkey
.time
;
2411 if ( GetKbdExtension()->UseExtension()
2412 && GetKbdExtension()->GetEventBase() == pEvent
->type
)
2414 GetKbdExtension()->Dispatch( pEvent
);
2420 std::list
< SalFrame
* >::iterator it
;
2421 for( it
= m_aFrames
.begin(); it
!= m_aFrames
.end(); ++it
)
2423 X11SalFrame
* pFrame
= static_cast< X11SalFrame
* >(*it
);
2424 XLIB_Window aDispatchWindow
= pEvent
->xany
.window
;
2425 if( pFrame
->GetWindow() == aDispatchWindow
2426 || pFrame
->GetShellWindow() == aDispatchWindow
2427 || pFrame
->GetForeignParent() == aDispatchWindow
2430 return pFrame
->Dispatch( pEvent
);
2432 if( pEvent
->type
== ConfigureNotify
&& pEvent
->xconfigure
.window
== pFrame
->GetStackingWindow() )
2434 return pFrame
->Dispatch( pEvent
);
2438 // dispatch to salobjects
2439 X11SalObject::Dispatch( pEvent
);
2441 // is this perhaps a root window that changed size ?
2442 processRandREvent( pEvent
);
2447 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2448 void SalDisplay::PrintEvent( const ByteString
&rComment
,
2449 XEvent
*pEvent
) const
2451 if( pEvent
->type
<= MappingNotify
)
2453 fprintf( stderr
, "[%s] %s s=%d w=%ld\n",
2454 rComment
.GetBuffer(),
2455 EventNames
[pEvent
->type
],
2456 pEvent
->xany
.send_event
,
2457 pEvent
->xany
.window
);
2459 switch( pEvent
->type
)
2463 fprintf( stderr
, "\t\ts=%d c=%d\n",
2465 pEvent
->xkey
.keycode
);
2470 fprintf( stderr
, "\t\ts=%d b=%d x=%d y=%d rx=%d ry=%d\n",
2471 pEvent
->xbutton
.state
,
2472 pEvent
->xbutton
.button
,
2475 pEvent
->xbutton
.x_root
,
2476 pEvent
->xbutton
.y_root
);
2480 fprintf( stderr
, "\t\ts=%d x=%d y=%d\n",
2481 pEvent
->xmotion
.state
,
2483 pEvent
->xmotion
.y
);
2488 fprintf( stderr
, "\t\tm=%d f=%d x=%d y=%d\n",
2489 pEvent
->xcrossing
.mode
,
2490 pEvent
->xcrossing
.focus
,
2491 pEvent
->xcrossing
.x
,
2492 pEvent
->xcrossing
.y
);
2497 fprintf( stderr
, "\t\tm=%d d=%d\n",
2498 pEvent
->xfocus
.mode
,
2499 pEvent
->xfocus
.detail
);
2503 case GraphicsExpose
:
2504 fprintf( stderr
, "\t\tc=%d %d*%d %d+%d\n",
2505 pEvent
->xexpose
.count
,
2506 pEvent
->xexpose
.width
,
2507 pEvent
->xexpose
.height
,
2509 pEvent
->xexpose
.y
);
2512 case VisibilityNotify
:
2513 fprintf( stderr
, "\t\ts=%d\n",
2514 pEvent
->xvisibility
.state
);
2525 case ReparentNotify
:
2526 fprintf( stderr
, "\t\tp=%d x=%d y=%d\n",
2527 sal::static_int_cast
< int >(pEvent
->xreparent
.parent
),
2528 pEvent
->xreparent
.x
,
2529 pEvent
->xreparent
.y
);
2532 case ConfigureNotify
:
2533 fprintf( stderr
, "\t\tb=%d %d*%d %d+%d\n",
2534 pEvent
->xconfigure
.border_width
,
2535 pEvent
->xconfigure
.width
,
2536 pEvent
->xconfigure
.height
,
2537 pEvent
->xconfigure
.x
,
2538 pEvent
->xconfigure
.y
);
2541 case PropertyNotify
:
2542 fprintf( stderr
, "\t\ta=%s (0x%X)\n",
2543 GetAtomName( pDisp_
, pEvent
->xproperty
.atom
),
2544 sal::static_int_cast
< unsigned int >(
2545 pEvent
->xproperty
.atom
) );
2548 case ColormapNotify
:
2549 fprintf( stderr
, "\t\tc=%ld n=%d s=%d\n",
2550 pEvent
->xcolormap
.colormap
,
2551 pEvent
->xcolormap
.c_new
,
2552 pEvent
->xcolormap
.state
);
2556 fprintf( stderr
, "\t\ta=%s (0x%X) f=%i [0x%lX,0x%lX,0x%lX,0x%lX,0x%lX])\n",
2557 GetAtomName( pDisp_
, pEvent
->xclient
.message_type
),
2558 sal::static_int_cast
< unsigned int >(
2559 pEvent
->xclient
.message_type
),
2560 pEvent
->xclient
.format
,
2561 pEvent
->xclient
.data
.l
[0],
2562 pEvent
->xclient
.data
.l
[1],
2563 pEvent
->xclient
.data
.l
[2],
2564 pEvent
->xclient
.data
.l
[3],
2565 pEvent
->xclient
.data
.l
[4] );
2569 fprintf( stderr
, "\t\tr=%sd\n",
2570 MappingModifier
== pEvent
->xmapping
.request
2572 : MappingKeyboard
== pEvent
->xmapping
.request
2574 : "MappingPointer" );
2580 fprintf( stderr
, "[%s] %d s=%d w=%ld\n",
2581 rComment
.GetBuffer(),
2583 pEvent
->xany
.send_event
,
2584 pEvent
->xany
.window
);
2587 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2588 void SalDisplay::PrintInfo() const
2592 fprintf( stderr
, "\n" );
2593 fprintf( stderr
, "Environment\n" );
2594 fprintf( stderr
, "\t$XENVIRONMENT \t\"%s\"\n",
2595 GetEnv( "XENVIRONMENT" ) );
2596 fprintf( stderr
, "\t$DISPLAY \t\"%s\"\n",
2597 GetEnv( "DISPLAY" ) );
2598 fprintf( stderr
, "\t$SAL_VISUAL \t\"%s\"\n",
2599 GetEnv( "SAL_VISUAL" ) );
2600 fprintf( stderr
, "\t$SAL_FONTPATH \t\"%s\"\n",
2601 GetEnv( "SAL_FONTPATH" ) );
2602 fprintf( stderr
, "\t$SAL_NOSEGV \t\"%s\"\n",
2603 GetEnv( "SAL_NOSEGV" ) );
2604 fprintf( stderr
, "\t$SAL_IGNOREXERRORS\t\"%s\"\n",
2605 GetEnv( "SAL_IGNOREXERRORS" ) );
2606 fprintf( stderr
, "\t$SAL_PROPERTIES \t\"%s\"\n",
2607 GetEnv( "SAL_PROPERTIES" ) );
2608 fprintf( stderr
, "\t$SAL_WM \t\"%s\"\n",
2609 GetEnv( "SAL_WM" ) );
2610 fprintf( stderr
, "\t$SAL_SYNCHRONIZE \t\"%s\"\n",
2611 GetEnv( "SAL_SYNCHRONIZE" ) );
2613 char sHostname
[ 120 ];
2614 gethostname (sHostname
, 120 );
2615 fprintf( stderr
, "Client\n" );
2616 fprintf( stderr
, "\tHost \t\"%s\"\n",
2619 fprintf( stderr
, "Display\n" );
2620 fprintf( stderr
, "\tHost \t\"%s\"\n",
2621 DisplayString(pDisp_
) );
2622 fprintf( stderr
, "\tVendor (Release) \t\"%s (%d)\"\n",
2623 ServerVendor(pDisp_
), VendorRelease(pDisp_
) );
2624 fprintf( stderr
, "\tProtocol \t%d.%d\n",
2625 ProtocolVersion(pDisp_
), ProtocolRevision(pDisp_
) );
2626 fprintf( stderr
, "\tScreen (count,def)\t%d (%d,%d)\n",
2627 m_nDefaultScreen
, ScreenCount(pDisp_
), DefaultScreen(pDisp_
) );
2628 fprintf( stderr
, "\tshift ctrl alt \t%s (0x%X) %s (0x%X) %s (0x%X)\n",
2629 KeyStr( nShiftKeySym_
), sal::static_int_cast
< unsigned int >(nShiftKeySym_
),
2630 KeyStr( nCtrlKeySym_
), sal::static_int_cast
< unsigned int >(nCtrlKeySym_
),
2631 KeyStr( nMod1KeySym_
), sal::static_int_cast
< unsigned int >(nMod1KeySym_
) );
2632 if( XExtendedMaxRequestSize(pDisp_
) * 4 )
2633 fprintf( stderr
, "\tXMaxRequestSize \t%ld %ld [bytes]\n",
2634 XMaxRequestSize(pDisp_
) * 4, XExtendedMaxRequestSize(pDisp_
) * 4 );
2635 if( GetProperties() != PROPERTY_DEFAULT
)
2636 fprintf( stderr
, "\tProperties \t0x%lX\n", GetProperties() );
2637 if( eWindowManager_
!= otherwm
)
2638 fprintf( stderr
, "\tWindowmanager \t%d\n", eWindowManager_
);
2640 fprintf( stderr
, "Screen\n" );
2641 fprintf( stderr
, "\tResolution/Size \t%ld*%ld %ld*%ld %.1lf\"\n",
2642 aResolution_
.A(), aResolution_
.B(),
2643 m_aScreens
[m_nDefaultScreen
].m_aSize
.Width(), m_aScreens
[m_nDefaultScreen
].m_aSize
.Height(),
2644 Hypothenuse( DisplayWidthMM ( pDisp_
, m_nDefaultScreen
),
2645 DisplayHeightMM( pDisp_
, m_nDefaultScreen
) ) / 25.4 );
2646 fprintf( stderr
, "\tBlack&White \t%lu %lu\n",
2647 GetColormap(m_nDefaultScreen
).GetBlackPixel(), GetColormap(m_nDefaultScreen
).GetWhitePixel() );
2648 fprintf( stderr
, "\tRGB \t0x%lx 0x%lx 0x%lx\n",
2649 GetVisual(m_nDefaultScreen
).red_mask
, GetVisual(m_nDefaultScreen
).green_mask
, GetVisual(m_nDefaultScreen
).blue_mask
);
2650 fprintf( stderr
, "\tVisual \t%d-bit %s ID=0x%x\n",
2651 GetVisual(m_nDefaultScreen
).GetDepth(),
2652 VisualClassName
[ GetVisual(m_nDefaultScreen
).GetClass() ],
2653 sal::static_int_cast
< unsigned int >(GetVisual(m_nDefaultScreen
).GetVisualId()) );
2656 void SalDisplay::InitXinerama()
2658 if( m_aScreens
.size() > 1 )
2660 m_bXinerama
= false;
2661 return; // multiple screens mean no xinerama
2664 #if defined(USE_XINERAMA_XSUN)
2665 int nFramebuffers
= 1;
2666 if( XineramaGetState( pDisp_
, m_nDefaultScreen
) )
2668 XRectangle pFramebuffers
[MAXFRAMEBUFFERS
];
2669 unsigned char hints
[MAXFRAMEBUFFERS
];
2670 int result
= XineramaGetInfo( pDisp_
,
2675 if( result
> 0 && nFramebuffers
> 1 )
2678 m_aXineramaScreens
= std::vector
<Rectangle
>( nFramebuffers
);
2679 for( int i
= 0; i
< nFramebuffers
; i
++ )
2680 m_aXineramaScreens
[i
] = Rectangle( Point( pFramebuffers
[i
].x
,
2681 pFramebuffers
[i
].y
),
2682 Size( pFramebuffers
[i
].width
,
2683 pFramebuffers
[i
].height
) );
2686 #elif defined(USE_XINERAMA_XORG)
2687 #if defined( X86 ) || defined( X86_64 )
2688 if( XineramaIsActive( pDisp_
) )
2690 int nFramebuffers
= 1;
2691 XineramaScreenInfo
* pScreens
= XineramaQueryScreens( pDisp_
, &nFramebuffers
);
2694 if( nFramebuffers
> 1 )
2696 m_aXineramaScreens
= std::vector
<Rectangle
>();
2697 for( int i
= 0; i
< nFramebuffers
; i
++ )
2699 // see if any frame buffers are at the same coordinates
2700 // this can happen with weird configuration e.g. on
2701 // XFree86 and Clone displays
2702 bool bDuplicate
= false;
2703 for( int n
= 0; n
< i
; n
++ )
2705 if( m_aXineramaScreens
[n
].Left() == pScreens
[i
].x_org
&&
2706 m_aXineramaScreens
[n
].Top() == pScreens
[i
].y_org
)
2709 if( m_aXineramaScreens
[n
].GetWidth() < pScreens
[i
].width
||
2710 m_aXineramaScreens
[n
].GetHeight() < pScreens
[i
].height
)
2712 m_aXineramaScreens
[n
].SetSize( Size( pScreens
[i
].width
,
2713 pScreens
[i
].height
) );
2719 m_aXineramaScreens
.push_back( Rectangle( Point( pScreens
[i
].x_org
,
2720 pScreens
[i
].y_org
),
2721 Size( pScreens
[i
].width
,
2722 pScreens
[i
].height
) ) );
2724 m_bXinerama
= m_aXineramaScreens
.size() > 1;
2731 #if OSL_DEBUG_LEVEL > 1
2734 for( std::vector
< Rectangle
>::const_iterator it
= m_aXineramaScreens
.begin(); it
!= m_aXineramaScreens
.end(); ++it
)
2735 fprintf( stderr
, "Xinerama screen: %ldx%ld+%ld+%ld\n", it
->GetWidth(), it
->GetHeight(), it
->Left(), it
->Top() );
2738 #endif // USE_XINERAMA
2741 void SalDisplay::registerFrame( SalFrame
* pFrame
)
2743 m_aFrames
.push_front( pFrame
);
2746 void SalDisplay::deregisterFrame( SalFrame
* pFrame
)
2748 if( osl_acquireMutex( hEventGuard_
) )
2750 std::list
< SalUserEvent
>::iterator it
= m_aUserEvents
.begin();
2751 while ( it
!= m_aUserEvents
.end() )
2753 if( it
->m_pFrame
== pFrame
)
2754 it
= m_aUserEvents
.erase( it
);
2758 osl_releaseMutex( hEventGuard_
);
2761 DBG_ERROR( "SalDisplay::deregisterFrame !acquireMutex\n" );
2764 m_aFrames
.remove( pFrame
);
2770 static Bool
timestamp_predicate( Display
*, XEvent
* i_pEvent
, XPointer i_pArg
)
2772 SalDisplay
* pSalDisplay
= reinterpret_cast<SalDisplay
*>(i_pArg
);
2773 if( i_pEvent
->type
== PropertyNotify
&&
2774 i_pEvent
->xproperty
.window
== pSalDisplay
->GetDrawable( pSalDisplay
->GetDefaultScreenNumber() ) &&
2775 i_pEvent
->xproperty
.atom
== pSalDisplay
->getWMAdaptor()->getAtom( WMAdaptor::SAL_GETTIMEEVENT
)
2783 XLIB_Time
SalDisplay::GetLastUserEventTime( bool i_bAlwaysReget
) const
2785 if( m_nLastUserEventTime
== CurrentTime
|| i_bAlwaysReget
)
2787 // get current server time
2788 unsigned char c
= 0;
2790 Atom nAtom
= getWMAdaptor()->getAtom( WMAdaptor::SAL_GETTIMEEVENT
);
2791 XChangeProperty( GetDisplay(), GetDrawable( GetDefaultScreenNumber() ),
2792 nAtom
, nAtom
, 8, PropModeReplace
, &c
, 1 );
2793 XFlush( GetDisplay() );
2795 if( ! XIfEventWithTimeout( &aEvent
, (XPointer
)this, timestamp_predicate
) )
2797 // this should not happen at all; still sometimes it happens
2798 aEvent
.xproperty
.time
= CurrentTime
;
2801 m_nLastUserEventTime
= aEvent
.xproperty
.time
;
2803 return m_nLastUserEventTime
;
2806 bool SalDisplay::XIfEventWithTimeout( XEvent
* o_pEvent
, XPointer i_pPredicateData
,
2807 X_if_predicate i_pPredicate
, long i_nTimeout
) const
2809 /* #i99360# ugly workaround an X11 library bug
2810 this replaces the following call:
2811 XIfEvent( GetDisplay(), o_pEvent, i_pPredicate, i_pPredicateData );
2815 if( ! XCheckIfEvent( GetDisplay(), o_pEvent
, i_pPredicate
, i_pPredicateData
) )
2817 // wait for some event to arrive
2819 aFD
.fd
= ConnectionNumber(GetDisplay());
2820 aFD
.events
= POLLIN
;
2822 poll( &aFD
, 1, i_nTimeout
);
2823 if( ! XCheckIfEvent( GetDisplay(), o_pEvent
, i_pPredicate
, i_pPredicateData
) )
2825 poll( &aFD
, 1, i_nTimeout
); // try once more for a packet of events from the Xserver
2826 if( ! XCheckIfEvent( GetDisplay(), o_pEvent
, i_pPredicate
, i_pPredicateData
) )
2835 // -=-= SalVisual -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2836 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2837 SalVisual::SalVisual()
2839 rtl_zeroMemory( this, sizeof( SalVisual
) );
2842 SalVisual::SalVisual( const XVisualInfo
* pXVI
)
2844 *(XVisualInfo
*)this = *pXVI
;
2845 if( GetClass() == TrueColor
)
2847 nRedShift_
= sal_Shift( red_mask
);
2848 nGreenShift_
= sal_Shift( green_mask
);
2849 nBlueShift_
= sal_Shift( blue_mask
);
2851 nRedBits_
= sal_significantBits( red_mask
);
2852 nGreenBits_
= sal_significantBits( green_mask
);
2853 nBlueBits_
= sal_significantBits( blue_mask
);
2855 if( GetDepth() == 24 )
2856 if( red_mask
== 0xFF0000 )
2857 if( green_mask
== 0xFF00 )
2858 if( blue_mask
== 0xFF )
2862 else if( blue_mask
== 0xFF00 )
2863 if( green_mask
== 0xFF )
2869 else if( green_mask
== 0xFF0000 )
2870 if( red_mask
== 0xFF00 )
2871 if( blue_mask
== 0xFF )
2875 else if( blue_mask
== 0xFF00 )
2876 if( red_mask
== 0xFF )
2882 else if( blue_mask
== 0xFF0000 )
2883 if( red_mask
== 0xFF00 )
2884 if( green_mask
== 0xFF )
2888 else if( green_mask
== 0xFF00 )
2889 if( red_mask
== 0xFF )
2902 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2903 SalVisual::~SalVisual()
2905 if( -1 == screen
&& VisualID(-1) == visualid
) delete visual
;
2908 // Konvertiert die Reihenfolge der Bytes eines Pixel in Bytes eines SalColors
2909 // fuer die 6 XXXA ist das nicht reversibel
2910 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2911 // SalColor is RGB (ABGR) a=0xFF000000, r=0xFF0000, g=0xFF00, b=0xFF
2913 #define SALCOLOR RGB
2914 #define SALCOLORREVERSE BGR
2916 BOOL
SalVisual::Convert( int &n0
, int &n1
, int &n2
, int &n3
)
2926 case SALCOLORREVERSE
:
2931 return Convert( n0
, n1
, n2
);
2945 fprintf( stderr
, "SalVisual::Convert %d\n", GetMode() );
2951 BOOL
SalVisual::Convert( int &n0
, int &n1
, int &n2
)
2971 case SALCOLORREVERSE
:
2989 fprintf( stderr
, "SalVisual::Convert %d\n", GetMode() );
2995 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2996 SalColor
SalVisual::GetTCColor( Pixel nPixel
) const
2998 if( SALCOLOR
== eRGBMode_
)
2999 return (SalColor
)nPixel
;
3001 if( SALCOLORREVERSE
== eRGBMode_
)
3002 return MAKE_SALCOLOR( (nPixel
& 0x0000FF),
3003 (nPixel
& 0x00FF00) >> 8,
3004 (nPixel
& 0xFF0000) >> 16);
3006 Pixel r
= nPixel
& red_mask
;
3007 Pixel g
= nPixel
& green_mask
;
3008 Pixel b
= nPixel
& blue_mask
;
3010 if( other
!= eRGBMode_
) // 8+8+8=24
3011 return MAKE_SALCOLOR( r
>> nRedShift_
,
3015 if( nRedShift_
> 0 ) r
>>= nRedShift_
; else r
<<= -nRedShift_
;
3016 if( nGreenShift_
> 0 ) g
>>= nGreenShift_
; else g
<<= -nGreenShift_
;
3017 if( nBlueShift_
> 0 ) b
>>= nBlueShift_
; else b
<<= -nBlueShift_
;
3019 if( nRedBits_
!= 8 )
3020 r
|= (r
& 0xff) >> (8-nRedBits_
);
3021 if( nGreenBits_
!= 8 )
3022 g
|= (g
& 0xff) >> (8-nGreenBits_
);
3023 if( nBlueBits_
!= 8 )
3024 b
|= (b
& 0xff) >> (8-nBlueBits_
);
3026 return MAKE_SALCOLOR( r
, g
, b
);
3029 Pixel
SalVisual::GetTCPixel( SalColor nSalColor
) const
3031 if( SALCOLOR
== eRGBMode_
)
3032 return (Pixel
)nSalColor
;
3034 Pixel r
= (Pixel
)SALCOLOR_RED( nSalColor
);
3035 Pixel g
= (Pixel
)SALCOLOR_GREEN( nSalColor
);
3036 Pixel b
= (Pixel
)SALCOLOR_BLUE( nSalColor
);
3038 if( SALCOLORREVERSE
== eRGBMode_
)
3039 return (b
<< 16) | (g
<< 8) | (r
);
3041 if( other
!= eRGBMode_
) // 8+8+8=24
3042 return (r
<< nRedShift_
) | (g
<< nGreenShift_
) | (b
<< nBlueShift_
);
3044 if( nRedShift_
> 0 ) r
<<= nRedShift_
; else r
>>= -nRedShift_
;
3045 if( nGreenShift_
> 0 ) g
<<= nGreenShift_
; else g
>>= -nGreenShift_
;
3046 if( nBlueShift_
> 0 ) b
<<= nBlueShift_
; else b
>>= -nBlueShift_
;
3048 return (r
&red_mask
) | (g
&green_mask
) | (b
&blue_mask
);
3051 // -=-= SalColormap -=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3052 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3053 SalColormap::SalColormap( const SalDisplay
*pDisplay
, Colormap hColormap
, int nScreen
)
3054 : m_pDisplay( pDisplay
),
3055 m_hColormap( hColormap
),
3056 m_nScreen( nScreen
)
3058 m_aVisual
= m_pDisplay
->GetVisual( m_nScreen
);
3062 GetXPixel( aColor
, 0x00, 0x00, 0x00 );
3063 m_nBlackPixel
= aColor
.pixel
;
3065 GetXPixel( aColor
, 0xFF, 0xFF, 0xFF );
3066 m_nWhitePixel
= aColor
.pixel
;
3068 m_nUsed
= 1 << m_aVisual
.GetDepth();
3070 if( m_aVisual
.GetClass() == PseudoColor
)
3074 // black, white, gray, ~gray = 4
3075 GetXPixels( aColor
, 0xC0, 0xC0, 0xC0 );
3077 // light colors: 3 * 2 = 6
3078 // GetXPixels( aColor, 0x00, 0x00, 0x00 );
3079 GetXPixels( aColor
, 0x00, 0x00, 0xFF );
3080 GetXPixels( aColor
, 0x00, 0xFF, 0x00 );
3081 GetXPixels( aColor
, 0x00, 0xFF, 0xFF );
3082 // GetXPixels( aColor, 0xFF, 0x00, 0x00 );
3083 // GetXPixels( aColor, 0xFF, 0x00, 0xFF );
3084 // GetXPixels( aColor, 0xFF, 0xFF, 0x00 );
3085 // GetXPixels( aColor, 0xFF, 0xFF, 0xFF );
3087 // standard colors: 7 * 2 = 14
3088 // GetXPixels( aColor, 0x00, 0x00, 0x00 );
3089 GetXPixels( aColor
, 0x00, 0x00, 0x80 );
3090 GetXPixels( aColor
, 0x00, 0x80, 0x00 );
3091 GetXPixels( aColor
, 0x00, 0x80, 0x80 );
3092 GetXPixels( aColor
, 0x80, 0x00, 0x00 );
3093 GetXPixels( aColor
, 0x80, 0x00, 0x80 );
3094 GetXPixels( aColor
, 0x80, 0x80, 0x00 );
3095 GetXPixels( aColor
, 0x80, 0x80, 0x80 );
3096 GetXPixels( aColor
, 0x00, 0xB8, 0xFF ); // Blau 7
3098 // cube: 6*6*6 - 8 = 208
3099 for( r
= 0; r
< 0x100; r
+= 0x33 ) // 0x33, 0x66, 0x99, 0xCC, 0xFF
3100 for( g
= 0; g
< 0x100; g
+= 0x33 )
3101 for( b
= 0; b
< 0x100; b
+= 0x33 )
3102 GetXPixels( aColor
, r
, g
, b
);
3104 // gray: 16 - 6 = 10
3105 for( g
= 0x11; g
< 0xFF; g
+= 0x11 )
3106 GetXPixels( aColor
, g
, g
, g
);
3108 // green: 16 - 6 = 10
3109 for( g
= 0x11; g
< 0xFF; g
+= 0x11 )
3110 GetXPixels( aColor
, 0, g
, 0 );
3113 for( r
= 0x11; r
< 0xFF; r
+= 0x11 )
3114 GetXPixels( aColor
, r
, 0, 0 );
3116 // blue: 16 - 6 = 10
3117 for( b
= 0x11; b
< 0xFF; b
+= 0x11 )
3118 GetXPixels( aColor
, 0, 0, b
);
3123 SalColormap::SalColormap( const BitmapPalette
&rPalette
)
3124 : m_pDisplay( GetX11SalData()->GetDisplay() ),
3125 m_hColormap( None
),
3126 m_nWhitePixel( SALCOLOR_NONE
),
3127 m_nBlackPixel( SALCOLOR_NONE
),
3128 m_nUsed( rPalette
.GetEntryCount() ),
3129 m_nScreen( GetX11SalData()->GetDisplay()->GetDefaultScreenNumber() )
3131 m_aPalette
= std::vector
<SalColor
>(m_nUsed
);
3133 for( unsigned int i
= 0; i
< m_nUsed
; i
++ )
3135 const BitmapColor
&rColor
= rPalette
[i
];
3136 m_aPalette
[i
] = MAKE_SALCOLOR( rColor
.GetRed(),
3139 if( (m_nBlackPixel
== SALCOLOR_NONE
) && (SALCOLOR_BLACK
== m_aPalette
[i
]) )
3141 else if( (m_nWhitePixel
== SALCOLOR_NONE
) && (SALCOLOR_WHITE
== m_aPalette
[i
]) )
3147 SalColormap::SalColormap()
3148 : m_pDisplay( GetX11SalData()->GetDisplay() ),
3149 m_hColormap( None
),
3156 m_nScreen
= m_pDisplay
->GetDefaultScreenNumber();
3157 m_aPalette
= std::vector
<SalColor
>(m_nUsed
);
3159 m_aPalette
[m_nBlackPixel
] = SALCOLOR_BLACK
;
3160 m_aPalette
[m_nWhitePixel
] = SALCOLOR_WHITE
;
3164 SalColormap::SalColormap( USHORT nDepth
)
3165 : m_pDisplay( GetX11SalData()->GetDisplay() ),
3166 m_hColormap( None
),
3167 m_nWhitePixel( (1 << nDepth
) - 1 ),
3168 m_nBlackPixel( 0x00000000 ),
3169 m_nUsed( 1 << nDepth
),
3170 m_nScreen( GetX11SalData()->GetDisplay()->GetDefaultScreenNumber() )
3172 const SalVisual
*pVisual
= &m_pDisplay
->GetVisual( m_nScreen
);
3174 if( pVisual
->GetClass() == TrueColor
&& pVisual
->GetDepth() == nDepth
)
3175 m_aVisual
= *pVisual
;
3180 if( !XMatchVisualInfo( m_pDisplay
->GetDisplay(),
3181 m_pDisplay
->GetDefaultScreenNumber(),
3186 aVI
.visual
= new Visual();
3187 aVI
.visualid
= (VisualID
)0; // beware of temporary destructor below
3190 aVI
.c_class
= TrueColor
;
3191 if( 24 == nDepth
) // 888
3193 aVI
.red_mask
= 0xFF0000;
3194 aVI
.green_mask
= 0x00FF00;
3195 aVI
.blue_mask
= 0x0000FF;
3197 else if( 16 == nDepth
) // 565
3199 aVI
.red_mask
= 0x00F800;
3200 aVI
.green_mask
= 0x0007E0;
3201 aVI
.blue_mask
= 0x00001F;
3203 else if( 15 == nDepth
) // 555
3205 aVI
.red_mask
= 0x007C00;
3206 aVI
.green_mask
= 0x0003E0;
3207 aVI
.blue_mask
= 0x00001F;
3209 else if( 12 == nDepth
) // 444
3211 aVI
.red_mask
= 0x000F00;
3212 aVI
.green_mask
= 0x0000F0;
3213 aVI
.blue_mask
= 0x00000F;
3215 else if( 8 == nDepth
) // 332
3217 aVI
.red_mask
= 0x0000E0;
3218 aVI
.green_mask
= 0x00001C;
3219 aVI
.blue_mask
= 0x000003;
3223 aVI
.red_mask
= 0x000000;
3224 aVI
.green_mask
= 0x000000;
3225 aVI
.blue_mask
= 0x000000;
3227 aVI
.colormap_size
= 0;
3228 aVI
.bits_per_rgb
= 8;
3230 aVI
.visual
->ext_data
= NULL
;
3231 aVI
.visual
->visualid
= aVI
.visualid
;
3232 aVI
.visual
->c_class
= aVI
.c_class
;
3233 aVI
.visual
->red_mask
= aVI
.red_mask
;
3234 aVI
.visual
->green_mask
= aVI
.green_mask
;
3235 aVI
.visual
->blue_mask
= aVI
.blue_mask
;
3236 aVI
.visual
->bits_per_rgb
= aVI
.bits_per_rgb
;
3237 aVI
.visual
->map_entries
= aVI
.colormap_size
;
3239 m_aVisual
= SalVisual( &aVI
);
3240 // give ownership of constructed Visual() to m_aVisual
3241 // see SalVisual destructor
3242 m_aVisual
.visualid
= (VisualID
)-1;
3243 m_aVisual
.screen
= -1;
3246 m_aVisual
= SalVisual( &aVI
);
3250 SalColormap::~SalColormap()
3253 m_hColormap
= (Colormap
)ILLEGAL_POINTER
;
3254 m_pDisplay
= (SalDisplay
*)ILLEGAL_POINTER
;
3258 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3259 void SalColormap::SetPalette( const BitmapPalette
&rPalette
)
3261 if( this != &GetX11SalData()->GetDisplay()->GetColormap(m_nScreen
) )
3263 m_nBlackPixel
= SALCOLOR_NONE
;
3264 m_nWhitePixel
= SALCOLOR_NONE
;
3267 if( rPalette
.GetEntryCount() > m_nUsed
)
3269 m_nBlackPixel
= SALCOLOR_NONE
;
3270 m_nWhitePixel
= SALCOLOR_NONE
;
3271 m_nUsed
= rPalette
.GetEntryCount();
3272 m_aPalette
= std::vector
<SalColor
>(m_nUsed
);
3275 for( int i
= 0; i
< rPalette
.GetEntryCount(); i
++ )
3277 const BitmapColor
&rColor
= rPalette
[i
];
3278 m_aPalette
[i
] = MAKE_SALCOLOR( rColor
.GetRed(),
3281 if( (m_nBlackPixel
== SALCOLOR_NONE
) && (SALCOLOR_BLACK
== m_aPalette
[i
]) )
3283 else if( (m_nWhitePixel
== SALCOLOR_NONE
) && (SALCOLOR_WHITE
== m_aPalette
[i
]) )
3288 void SalColormap::GetPalette()
3291 m_aPalette
= std::vector
<SalColor
>(m_nUsed
);
3293 XColor
*aColor
= new XColor
[m_nUsed
];
3295 for( i
= 0; i
< m_nUsed
; i
++ )
3297 aColor
[i
].red
= aColor
[i
].green
= aColor
[i
].blue
= 0;
3298 aColor
[i
].pixel
= i
;
3301 XQueryColors( m_pDisplay
->GetDisplay(), m_hColormap
, aColor
, m_nUsed
);
3303 for( i
= 0; i
< m_nUsed
; i
++ )
3305 m_aPalette
[i
] = MAKE_SALCOLOR( aColor
[i
].red
>> 8,
3306 aColor
[i
].green
>> 8,
3307 aColor
[i
].blue
>> 8 );
3313 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3314 static USHORT
sal_Lookup( const std::vector
<SalColor
>& rPalette
,
3315 int r
, int g
, int b
,
3319 int nBest
= ColorDiff( rPalette
[0], r
, g
, b
);
3321 for( USHORT i
= 1; i
< nUsed
; i
++ )
3323 int n
= ColorDiff( rPalette
[i
], r
, g
, b
);
3337 void SalColormap::GetLookupTable()
3339 m_aLookupTable
= std::vector
<USHORT
>(16*16*16);
3342 for( int r
= 0; r
< 256; r
+= 17 )
3343 for( int g
= 0; g
< 256; g
+= 17 )
3344 for( int b
= 0; b
< 256; b
+= 17 )
3345 m_aLookupTable
[i
++] = sal_Lookup( m_aPalette
, r
, g
, b
, m_nUsed
);
3348 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3349 SalColor
SalColormap::GetColor( Pixel nPixel
) const
3351 if( m_nBlackPixel
== nPixel
) return SALCOLOR_BLACK
;
3352 if( m_nWhitePixel
== nPixel
) return SALCOLOR_WHITE
;
3354 if( m_aVisual
.GetVisual() )
3356 if( m_aVisual
.GetClass() == TrueColor
)
3357 return m_aVisual
.GetTCColor( nPixel
);
3359 if( m_aPalette
.empty()
3361 #ifdef PSEUDOCOLOR12
3362 && m_aVisual
.GetDepth() <= 12
3364 && m_aVisual
.GetDepth() <= 8
3366 && m_aVisual
.GetClass() == PseudoColor
)
3367 ((SalColormap
*)this)->GetPalette();
3370 if( !m_aPalette
.empty() && nPixel
< m_nUsed
)
3371 return m_aPalette
[nPixel
];
3375 DBG_ASSERT( 1, "SalColormap::GetColor() !hColormap_\n" );
3379 // DirectColor, StaticColor, StaticGray, GrayScale
3382 aColor
.pixel
= nPixel
;
3384 XQueryColor( m_pDisplay
->GetDisplay(), m_hColormap
, &aColor
);
3386 return MAKE_SALCOLOR( aColor
.red
>>8, aColor
.green
>>8, aColor
.blue
>>8 );
3389 inline BOOL
SalColormap::GetXPixel( XColor
&rColor
,
3394 rColor
.red
= r
* 257;
3395 rColor
.green
= g
* 257;
3396 rColor
.blue
= b
* 257;
3397 return XAllocColor( GetXDisplay(), m_hColormap
, &rColor
);
3400 BOOL
SalColormap::GetXPixels( XColor
&rColor
,
3405 if( !GetXPixel( rColor
, r
, g
, b
) )
3407 if( rColor
.pixel
& 1 )
3409 return GetXPixel( rColor
, r
^0xFF, g
^0xFF, b
^0xFF );
3412 Pixel
SalColormap::GetPixel( SalColor nSalColor
) const
3414 if( SALCOLOR_NONE
== nSalColor
) return 0;
3415 if( SALCOLOR_BLACK
== nSalColor
) return m_nBlackPixel
;
3416 if( SALCOLOR_WHITE
== nSalColor
) return m_nWhitePixel
;
3418 if( m_aVisual
.GetClass() == TrueColor
)
3419 return m_aVisual
.GetTCPixel( nSalColor
);
3421 if( m_aLookupTable
.empty() )
3423 if( m_aPalette
.empty()
3425 #ifdef PSEUDOCOLOR12
3426 && m_aVisual
.GetDepth() <= 12
3428 && m_aVisual
.GetDepth() <= 8
3430 && m_aVisual
.GetClass() == PseudoColor
) // what else ???
3431 ((SalColormap
*)this)->GetPalette();
3433 if( !m_aPalette
.empty() )
3434 for( Pixel i
= 0; i
< m_nUsed
; i
++ )
3435 if( m_aPalette
[i
] == nSalColor
)
3440 // DirectColor, StaticColor, StaticGray, GrayScale (PseudoColor)
3443 if( GetXPixel( aColor
,
3444 SALCOLOR_RED ( nSalColor
),
3445 SALCOLOR_GREEN( nSalColor
),
3446 SALCOLOR_BLUE ( nSalColor
) ) )
3448 if( !m_aPalette
.empty() && !m_aPalette
[aColor
.pixel
] )
3450 const_cast<SalColormap
*>(this)->m_aPalette
[aColor
.pixel
] = nSalColor
;
3452 if( !(aColor
.pixel
& 1) && !m_aPalette
[aColor
.pixel
+1] )
3454 XColor aInversColor
;
3456 SalColor nInversColor
= nSalColor
^ 0xFFFFFF;
3458 GetXPixel( aInversColor
,
3459 SALCOLOR_RED ( nInversColor
),
3460 SALCOLOR_GREEN( nInversColor
),
3461 SALCOLOR_BLUE ( nInversColor
) );
3463 if( !m_aPalette
[aInversColor
.pixel
] )
3464 const_cast<SalColormap
*>(this)->m_aPalette
[aInversColor
.pixel
] = nInversColor
;
3467 fprintf( stderr
, "SalColormap::GetPixel() 0x%06lx=%lu 0x%06lx=%lu\n",
3468 static_cast< unsigned long >(nSalColor
), aColor
.pixel
,
3469 static_cast< unsigned long >(nInversColor
), aInversColor
.pixel
);
3474 return aColor
.pixel
;
3478 fprintf( stderr
, "SalColormap::GetPixel() !XAllocColor %lx\n",
3479 static_cast< unsigned long >(nSalColor
) );
3483 if( m_aPalette
.empty() )
3486 fprintf( stderr
, "SalColormap::GetPixel() Palette empty %lx\n",
3487 static_cast< unsigned long >(nSalColor
));
3492 ((SalColormap
*)this)->GetLookupTable();
3495 // Colormatching ueber Palette
3496 USHORT r
= SALCOLOR_RED ( nSalColor
);
3497 USHORT g
= SALCOLOR_GREEN( nSalColor
);
3498 USHORT b
= SALCOLOR_BLUE ( nSalColor
);
3499 return m_aLookupTable
[ (((r
+8)/17) << 8)