LCOV - code coverage report
Current view: top level - libreoffice/vcl/unx/generic/app - saldisp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 1351 0.0 %
Date: 2012-12-27 Functions: 0 62 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <math.h>
      24             : #include <sys/time.h>
      25             : #include <pthread.h>
      26             : #include <unistd.h>
      27             : #include <ctype.h>
      28             : #include <string.h>
      29             : 
      30             : #if defined(SOLARIS) || defined(AIX)
      31             : #include <sal/alloca.h>
      32             : #include <osl/module.h>
      33             : #endif
      34             : 
      35             : #include <tools/prex.h>
      36             : #include <X11/cursorfont.h>
      37             : #include "unx/x11_cursors/salcursors.h"
      38             : #include "unx/x11_cursors/invert50.h"
      39             : #ifdef SOLARIS
      40             : #define XK_KOREAN
      41             : #endif
      42             : #include <X11/keysym.h>
      43             : #include <X11/XKBlib.h>
      44             : #include <X11/Xatom.h>
      45             : 
      46             : #ifdef USE_XINERAMA_XORG
      47             : #include <X11/extensions/Xinerama.h>
      48             : #elif defined USE_XINERAMA_XSUN
      49             : #if defined(SOLARIS) && defined(INTEL) // missing extension header in standard installation
      50             : #define MAXFRAMEBUFFERS       16
      51             : Bool XineramaGetState(Display*, int);
      52             : Status XineramaGetInfo(Display*, int, XRectangle*, unsigned char*, int*);
      53             : #else
      54             : #include <X11/extensions/xinerama.h>
      55             : #endif
      56             : #endif
      57             : 
      58             : #include <tools/postx.h>
      59             : 
      60             : #include <vcl/svapp.hxx>
      61             : #include <unx/salunx.h>
      62             : #include <sal/types.h>
      63             : #include "unx/i18n_im.hxx"
      64             : #include "unx/i18n_xkb.hxx"
      65             : #include <unx/saldisp.hxx>
      66             : #include <unx/saldata.hxx>
      67             : #include <salinst.hxx>
      68             : #include <unx/salgdi.h>
      69             : #include <unx/salframe.h>
      70             : #include <vcl/keycodes.hxx>
      71             : #include <unx/salbmp.h>
      72             : #include <osl/mutex.h>
      73             : #include <unx/salobj.h>
      74             : #include <unx/sm.hxx>
      75             : #include <unx/wmadaptor.hxx>
      76             : 
      77             : #include <osl/socket.h>
      78             : #include <poll.h>
      79             : 
      80             : using namespace vcl_sal;
      81             : 
      82             : using ::rtl::OUString;
      83             : 
      84             : // -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      85             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      86             : #define SALCOLOR_WHITE      MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF )
      87             : #define SALCOLOR_BLACK      MAKE_SALCOLOR( 0x00, 0x00, 0x00 )
      88             : 
      89             : // -=-= Prototyps =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      90             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      91             : // -=-= static variables -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      92             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
      93             : static const char* const EventNames[] =
      94             : {
      95             :     NULL,
      96             :     NULL,
      97             :     "KeyPress",
      98             :     "KeyRelease",
      99             :     "ButtonPress",
     100             :     "ButtonRelease",
     101             :     "MotionNotify",
     102             :     "EnterNotify",
     103             :     "LeaveNotify",
     104             :     "FocusIn",
     105             :     "FocusOut",
     106             :     "KeymapNotify",
     107             :     "Expose",
     108             :     "GraphicsExpose",
     109             :     "NoExpose",
     110             :     "VisibilityNotify",
     111             :     "CreateNotify",
     112             :     "DestroyNotify",
     113             :     "UnmapNotify",
     114             :     "MapNotify",
     115             :     "MapRequest",
     116             :     "ReparentNotify",
     117             :     "ConfigureNotify",
     118             :     "ConfigureRequest",
     119             :     "GravityNotify",
     120             :     "ResizeRequest",
     121             :     "CirculateNotify",
     122             :     "CirculateRequest",
     123             :     "PropertyNotify",
     124             :     "SelectionClear",
     125             :     "SelectionRequest",
     126             :     "SelectionNotify",
     127             :     "ColormapNotify",
     128             :     "ClientMessage",
     129             :     "MappingNotify"
     130             : };
     131             : 
     132             : // -=-= global inline =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     133             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     134           0 : inline const char *Null( const char *p ) { return p ? p : ""; }
     135           0 : inline const char *GetEnv( const char *p ) { return Null( getenv( p ) ); }
     136           0 : inline const char *KeyStr( KeySym n ) { return Null( XKeysymToString( n ) ); }
     137             : 
     138             : inline const char *GetAtomName( Display *d, Atom a )
     139             : { return Null( XGetAtomName( d, a ) ); }
     140             : 
     141           0 : inline double Hypothenuse( long w, long h )
     142           0 : { return sqrt( (double)((w*w)+(h*h)) ); }
     143             : 
     144           0 : inline int ColorDiff( int r, int g, int b )
     145           0 : { return (r*r)+(g*g)+(b*b); }
     146             : 
     147           0 : inline int ColorDiff( SalColor c1, int r, int g, int b )
     148             : { return ColorDiff( (int)SALCOLOR_RED  (c1)-r,
     149             :                     (int)SALCOLOR_GREEN(c1)-g,
     150           0 :                     (int)SALCOLOR_BLUE (c1)-b ); }
     151             : 
     152             : // -=-= global functions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     153             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     154           0 : static int sal_Shift( Pixel nMask )
     155             : {
     156           0 :     int i = 24;
     157           0 :     if( nMask < 0x00010000 ) { nMask <<= 16; i -= 16; }
     158           0 :     if( nMask < 0x01000000 ) { nMask <<=  8; i -=  8; }
     159           0 :     if( nMask < 0x10000000 ) { nMask <<=  4; i -=  4; }
     160           0 :     if( nMask < 0x40000000 ) { nMask <<=  2; i -=  2; }
     161           0 :     if( nMask < 0x80000000 ) { nMask <<=  1; i -=  1; }
     162           0 :     return i;
     163             : }
     164             : 
     165           0 : static int sal_significantBits( Pixel nMask )
     166             : {
     167           0 :     int nRotate = sizeof(Pixel)*4;
     168           0 :     int nBits = 0;
     169           0 :     while( nRotate-- )
     170             :     {
     171           0 :         if( nMask & 1 )
     172           0 :             nBits++;
     173           0 :         nMask >>= 1;
     174             :     }
     175           0 :     return nBits;
     176             : }
     177             : 
     178             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     179           0 : static sal_Bool sal_GetVisualInfo( Display *pDisplay, XID nVID, XVisualInfo &rVI )
     180             : {
     181             :     int         nInfos;
     182             :     XVisualInfo aTemplate;
     183             :     XVisualInfo*pInfos;
     184             : 
     185           0 :     aTemplate.visualid = nVID;
     186             : 
     187           0 :     pInfos = XGetVisualInfo( pDisplay, VisualIDMask, &aTemplate, &nInfos );
     188           0 :     if( !pInfos )
     189           0 :         return sal_False;
     190             : 
     191           0 :     rVI = *pInfos;
     192           0 :     XFree( pInfos );
     193             : 
     194             :     DBG_ASSERT( rVI.visualid == nVID,
     195             :                 "sal_GetVisualInfo: could not get correct visual by visualId" );
     196           0 :     return sal_True;
     197             : }
     198             : 
     199             : // ---------------------------------------------------------------------------
     200             : extern "C" srv_vendor_t
     201           0 : sal_GetServerVendor( Display *p_display )
     202             : {
     203             :     typedef struct {
     204             :         srv_vendor_t    e_vendor;   // vendor as enum
     205             :         const char      *p_name;    // vendor name as returned by VendorString()
     206             :         unsigned int    n_len;  // number of chars to compare
     207             :     } vendor_t;
     208             : 
     209             :     const vendor_t p_vendorlist[] = {
     210             :         { vendor_sun,         "Sun Microsystems, Inc.",          10 },
     211             :         // allways the last entry: vendor_none to indicate eol
     212             :         { vendor_none,        NULL,                               0 },
     213           0 :     };
     214             : 
     215             :     // handle regular server vendors
     216           0 :     char     *p_name   = ServerVendor( p_display );
     217             :     vendor_t *p_vendor;
     218           0 :     for (p_vendor = const_cast<vendor_t*>(p_vendorlist); p_vendor->e_vendor != vendor_none; p_vendor++)
     219             :     {
     220           0 :         if ( strncmp (p_name, p_vendor->p_name, p_vendor->n_len) == 0 )
     221           0 :             return p_vendor->e_vendor;
     222             :     }
     223             : 
     224             :     // vendor not found in list
     225           0 :     return vendor_unknown;
     226             : }
     227             : 
     228             : // -=-= SalDisplay -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     229             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     230           0 : sal_Bool SalDisplay::BestVisual( Display     *pDisplay,
     231             :                              int          nScreen,
     232             :                              XVisualInfo &rVI )
     233             : {
     234           0 :     VisualID nDefVID = XVisualIDFromVisual( DefaultVisual( pDisplay, nScreen ) );
     235           0 :     VisualID    nVID = 0;
     236           0 :     char       *pVID = getenv( "SAL_VISUAL" );
     237           0 :     if( pVID )
     238           0 :         sscanf( pVID, "%li", &nVID );
     239             : 
     240           0 :     if( nVID && sal_GetVisualInfo( pDisplay, nVID, rVI ) )
     241           0 :         return rVI.visualid == nDefVID;
     242             : 
     243             :     XVisualInfo aVI;
     244           0 :     aVI.screen = nScreen;
     245             :     // get all visuals
     246             :     int nVisuals;
     247             :     XVisualInfo* pVInfos = XGetVisualInfo( pDisplay, VisualScreenMask,
     248           0 :                                            &aVI, &nVisuals );
     249             :     // pVInfos should contain at least one visual, otherwise
     250             :     // we're in trouble
     251           0 :     int* pWeight = (int*)alloca( sizeof(int)*nVisuals );
     252             :     int i;
     253           0 :     for( i = 0; i < nVisuals; i++ )
     254             :     {
     255           0 :         sal_Bool bUsable = sal_False;
     256           0 :         int nTrueColor = 1;
     257             : 
     258           0 :         if ( pVInfos[i].screen != nScreen )
     259             :         {
     260           0 :             bUsable = sal_False;
     261             :         }
     262             :         else
     263           0 :         if( pVInfos[i].c_class == TrueColor )
     264             :         {
     265           0 :             nTrueColor = 2048;
     266           0 :             if( pVInfos[i].depth == 24 )
     267           0 :                 bUsable = sal_True;
     268             :         }
     269           0 :         else if( pVInfos[i].c_class == PseudoColor )
     270             :         {
     271           0 :             bUsable = sal_True;
     272             :         }
     273           0 :         pWeight[ i ] = bUsable ? nTrueColor*pVInfos[i].depth : -1024;
     274           0 :         pWeight[ i ] -= pVInfos[ i ].visualid;
     275             :     }
     276             : 
     277           0 :     int nBestVisual = 0;
     278           0 :     int nBestWeight = -1024;
     279           0 :     for( i = 0; i < nVisuals; i++ )
     280             :     {
     281           0 :         if( pWeight[ i ] > nBestWeight )
     282             :         {
     283           0 :             nBestWeight = pWeight[ i ];
     284           0 :             nBestVisual = i;
     285             :         }
     286             :     }
     287             : 
     288           0 :     rVI = pVInfos[ nBestVisual ];
     289             : 
     290           0 :     XFree( pVInfos );
     291           0 :     return rVI.visualid == nDefVID;
     292             : }
     293             : 
     294             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     295             : 
     296           0 : SalDisplay::SalDisplay( Display *display ) :
     297             :         mpInputMethod( NULL ),
     298             :         pDisp_( display ),
     299             :         m_nXDefaultScreen( 0 ),
     300             :         m_pWMAdaptor( NULL ),
     301             :         m_bUseRandRWrapper( true ),
     302           0 :         m_nLastUserEventTime( CurrentTime )
     303             : {
     304             : #if OSL_DEBUG_LEVEL > 1
     305             :     fprintf( stderr, "SalDisplay::SalDisplay()\n" );
     306             : #endif
     307           0 :     SalGenericData *pData = GetGenericData();
     308             : 
     309           0 :     pXLib_ = NULL;
     310             :     DBG_ASSERT( ! pData->GetDisplay(), "Second SalDisplay created !!!\n" );
     311           0 :     pData->SetDisplay( this );
     312             : 
     313           0 :     m_nXDefaultScreen = SalX11Screen( DefaultScreen( pDisp_ ) );
     314           0 : }
     315             : 
     316             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     317           0 : SalDisplay::~SalDisplay()
     318             : {
     319             : #if OSL_DEBUG_LEVEL > 1
     320             :     fprintf( stderr, "SalDisplay::~SalDisplay()\n" );
     321             : #endif
     322           0 :     if( pDisp_ )
     323             :     {
     324           0 :         doDestruct();
     325             : #if OSL_DEBUG_LEVEL > 1
     326             :         fprintf( stderr, "display %p closed\n", pDisp_ );
     327             : #endif
     328           0 :         pDisp_ = NULL;
     329             :     }
     330             :     // don't do this in doDestruct since RandR extension adds hooks into Display
     331             :     // that is XCloseDisplay still needs the RandR library if it was used
     332           0 :     DeInitRandR();
     333           0 : }
     334             : 
     335           0 : void SalDisplay::doDestruct()
     336             : {
     337           0 :     SalGenericData *pData = GetGenericData();
     338             : 
     339           0 :     delete m_pWMAdaptor;
     340           0 :     m_pWMAdaptor = NULL;
     341           0 :     X11SalBitmap::ImplDestroyCache();
     342           0 :     X11SalGraphics::releaseGlyphPeer();
     343             : 
     344           0 :     if( IsDisplay() )
     345             :     {
     346           0 :         delete mpInputMethod, mpInputMethod = NULL;
     347           0 :         delete mpKbdExtension, mpKbdExtension = NULL;
     348             : 
     349           0 :         for( unsigned int i = 0; i < m_aScreens.size(); i++ )
     350             :         {
     351           0 :             ScreenData& rData = m_aScreens[i];
     352           0 :             if( rData.m_bInit )
     353             :             {
     354           0 :                 if( rData.m_aMonoGC != rData.m_aCopyGC )
     355           0 :                     XFreeGC( pDisp_, rData.m_aMonoGC );
     356           0 :                 XFreeGC( pDisp_, rData.m_aCopyGC );
     357           0 :                 XFreeGC( pDisp_, rData.m_aAndInvertedGC );
     358           0 :                 XFreeGC( pDisp_, rData.m_aAndGC );
     359           0 :                 XFreeGC( pDisp_, rData.m_aOrGC );
     360           0 :                 XFreeGC( pDisp_, rData.m_aStippleGC );
     361           0 :                 XFreePixmap( pDisp_, rData.m_hInvert50 );
     362           0 :                 XDestroyWindow( pDisp_, rData.m_aRefWindow );
     363           0 :                 Colormap aColMap = rData.m_aColormap.GetXColormap();
     364           0 :                 if( aColMap != None && aColMap != DefaultColormap( pDisp_, i ) )
     365           0 :                     XFreeColormap( pDisp_, aColMap );
     366             :             }
     367             :         }
     368             : 
     369           0 :         for( size_t i = 0; i < POINTER_COUNT; i++ )
     370             :         {
     371           0 :             if( aPointerCache_[i] )
     372           0 :                 XFreeCursor( pDisp_, aPointerCache_[i] );
     373             :         }
     374             : 
     375           0 :         if( pXLib_ )
     376           0 :             pXLib_->Remove( ConnectionNumber( pDisp_ ) );
     377             :     }
     378             : 
     379           0 :     if( pData->GetDisplay() == static_cast<const SalGenericDisplay *>( this ) )
     380           0 :         pData->SetDisplay( NULL );
     381           0 : }
     382             : 
     383           0 : static int DisplayHasEvent( int fd, SalX11Display *pDisplay  )
     384             : {
     385             :   (void)fd;
     386             :   DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
     387             :               "wrong fd in DisplayHasEvent" );
     388           0 :   if( ! pDisplay->IsDisplay() )
     389           0 :       return 0;
     390             : 
     391             :   int result;
     392             : 
     393           0 :   GetSalData()->m_pInstance->GetYieldMutex()->acquire();
     394           0 :   result = pDisplay->IsEvent();
     395           0 :   GetSalData()->m_pInstance->GetYieldMutex()->release();
     396           0 :   return result;
     397             : }
     398           0 : static int DisplayQueue( int fd, SalX11Display *pDisplay )
     399             : {
     400             :   (void)fd;
     401             :   DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
     402             :               "wrong fd in DisplayHasEvent" );
     403             :   int result;
     404             : 
     405           0 :   GetSalData()->m_pInstance->GetYieldMutex()->acquire();
     406             :   result =  XEventsQueued( pDisplay->GetDisplay(),
     407           0 :                         QueuedAfterReading );
     408           0 :   GetSalData()->m_pInstance->GetYieldMutex()->release();
     409             : 
     410           0 :   return result;
     411             : }
     412           0 : static int DisplayYield( int fd, SalX11Display *pDisplay )
     413             : {
     414             :   (void)fd;
     415             :   DBG_ASSERT( ConnectionNumber( pDisplay->GetDisplay() ) == fd,
     416             :               "wrong fd in DisplayHasEvent" );
     417             : 
     418           0 :   GetSalData()->m_pInstance->GetYieldMutex()->acquire();
     419           0 :   pDisplay->Yield();
     420           0 :   GetSalData()->m_pInstance->GetYieldMutex()->release();
     421           0 :   return sal_True;
     422             : }
     423             : 
     424           0 : SalX11Display::SalX11Display( Display *display )
     425           0 :         : SalDisplay( display )
     426             : {
     427           0 :     Init();
     428             : 
     429           0 :     pXLib_ = GetX11SalData()->GetLib();
     430             :     pXLib_->Insert( ConnectionNumber( pDisp_ ),
     431             :                     this,
     432             :                     (YieldFunc) DisplayHasEvent,
     433             :                     (YieldFunc) DisplayQueue,
     434           0 :                     (YieldFunc) DisplayYield );
     435           0 : }
     436             : 
     437           0 : SalX11Display::~SalX11Display()
     438             : {
     439             : #if OSL_DEBUG_LEVEL > 1
     440             :     fprintf( stderr, "SalX11Display::~SalX11Display()\n" );
     441             : #endif
     442           0 :     if( pDisp_ )
     443             :     {
     444           0 :         doDestruct();
     445           0 :         XCloseDisplay( pDisp_ );
     446           0 :         pDisp_ = NULL;
     447             :     }
     448           0 : }
     449             : 
     450           0 : void SalX11Display::PostUserEvent()
     451             : {
     452           0 :     if( pXLib_ )
     453           0 :         pXLib_->PostUserEvent();
     454           0 : }
     455             : 
     456             : SalDisplay::ScreenData *
     457           0 : SalDisplay::initScreen( SalX11Screen nXScreen ) const
     458             : {
     459           0 :     if( nXScreen.getXScreen() >= m_aScreens.size() )
     460           0 :         nXScreen = m_nXDefaultScreen;
     461           0 :     ScreenData* pSD = const_cast<ScreenData *>(&m_aScreens[nXScreen.getXScreen()]);
     462           0 :     if( pSD->m_bInit )
     463           0 :         return NULL;
     464           0 :     pSD->m_bInit = true;
     465             : 
     466             :     XVisualInfo aVI;
     467             :     Colormap    aColMap;
     468             : 
     469           0 :     if( SalDisplay::BestVisual( pDisp_, nXScreen.getXScreen(), aVI ) ) // DefaultVisual
     470           0 :         aColMap = DefaultColormap( pDisp_, nXScreen.getXScreen() );
     471             :     else
     472             :         aColMap = XCreateColormap( pDisp_,
     473           0 :                                    RootWindow( pDisp_, nXScreen.getXScreen() ),
     474             :                                    aVI.visual,
     475           0 :                                    AllocNone );
     476             : 
     477           0 :     Screen* pScreen = ScreenOfDisplay( pDisp_, nXScreen.getXScreen() );
     478             : 
     479           0 :     pSD->m_aSize = Size( WidthOfScreen( pScreen ), HeightOfScreen( pScreen ) );
     480           0 :     pSD->m_aRoot = RootWindow( pDisp_, nXScreen.getXScreen() );
     481           0 :     pSD->m_aVisual = SalVisual( &aVI );
     482           0 :     pSD->m_aColormap = SalColormap( this, aColMap, nXScreen );
     483             : 
     484             :     // we're interested in configure notification of root windows
     485           0 :     InitRandR( pSD->m_aRoot );
     486             : 
     487             :     // - - - - - - - - - - Reference Window/Default Drawable - -
     488             :     XSetWindowAttributes aXWAttributes;
     489           0 :     aXWAttributes.border_pixel      = 0;
     490           0 :     aXWAttributes.background_pixel  = 0;
     491           0 :     aXWAttributes.colormap          = aColMap;
     492             :     pSD->m_aRefWindow     = XCreateWindow( pDisp_,
     493             :                                           pSD->m_aRoot,
     494             :                                           0,0, 16,16, 0,
     495             :                                           pSD->m_aVisual.GetDepth(),
     496             :                                           InputOutput,
     497             :                                           pSD->m_aVisual.GetVisual(),
     498             :                                           CWBorderPixel|CWBackPixel|CWColormap,
     499           0 :                                           &aXWAttributes );
     500             : 
     501             :     // set client leader (session id gets set when session is started)
     502           0 :     if( pSD->m_aRefWindow )
     503             :     {
     504             :         // client leader must have WM_CLIENT_LEADER pointing to itself
     505             :         XChangeProperty( pDisp_,
     506             :                          pSD->m_aRefWindow,
     507             :                          XInternAtom( pDisp_, "WM_CLIENT_LEADER", False ),
     508             :                          XA_WINDOW,
     509             :                          32,
     510             :                          PropModeReplace,
     511             :                          (unsigned char*)&pSD->m_aRefWindow,
     512             :                          1
     513           0 :                          );
     514             : 
     515           0 :         rtl::OString aExec(rtl::OUStringToOString(SessionManagerClient::getExecName(), osl_getThreadTextEncoding()));
     516             :         const char* argv[2];
     517           0 :         argv[0] = "/bin/sh";
     518           0 :         argv[1] = aExec.getStr();
     519           0 :         XSetCommand( pDisp_, pSD->m_aRefWindow, const_cast<char**>(argv), 2 );
     520           0 :         XSelectInput( pDisp_, pSD->m_aRefWindow, PropertyChangeMask );
     521             : 
     522             :         // - - - - - - - - - - GCs - - - - - - - - - - - - - - - - -
     523             :         XGCValues values;
     524           0 :         values.graphics_exposures   = False;
     525           0 :         values.fill_style           = FillOpaqueStippled;
     526           0 :         values.background           = (1<<pSD->m_aVisual.GetDepth())-1;
     527           0 :         values.foreground           = 0;
     528             : 
     529             :         pSD->m_aCopyGC       = XCreateGC( pDisp_,
     530             :                                          pSD->m_aRefWindow,
     531             :                                          GCGraphicsExposures
     532             :                                          | GCForeground
     533             :                                          | GCBackground,
     534           0 :                                          &values );
     535             :         pSD->m_aAndInvertedGC= XCreateGC( pDisp_,
     536             :                                          pSD->m_aRefWindow,
     537             :                                          GCGraphicsExposures
     538             :                                          | GCForeground
     539             :                                          | GCBackground,
     540           0 :                                          &values );
     541             :         pSD->m_aAndGC        = XCreateGC( pDisp_,
     542             :                                          pSD->m_aRefWindow,
     543             :                                          GCGraphicsExposures
     544             :                                          | GCForeground
     545             :                                          | GCBackground,
     546           0 :                                          &values );
     547             :         pSD->m_aOrGC         = XCreateGC( pDisp_,
     548             :                                          pSD->m_aRefWindow,
     549             :                                          GCGraphicsExposures
     550             :                                          | GCForeground
     551             :                                          | GCBackground,
     552           0 :                                          &values    );
     553             :         pSD->m_aStippleGC    = XCreateGC( pDisp_,
     554             :                                          pSD->m_aRefWindow,
     555             :                                          GCGraphicsExposures
     556             :                                          | GCFillStyle
     557             :                                          | GCForeground
     558             :                                          | GCBackground,
     559           0 :                                          &values );
     560             : 
     561           0 :         XSetFunction( pDisp_, pSD->m_aAndInvertedGC,  GXandInverted );
     562           0 :         XSetFunction( pDisp_, pSD->m_aAndGC,          GXand );
     563             :         // PowerPC Solaris 2.5 (XSun 3500) Bug: GXor = GXnop
     564           0 :         XSetFunction( pDisp_, pSD->m_aOrGC,           GXxor );
     565             : 
     566           0 :         if( 1 == pSD->m_aVisual.GetDepth() )
     567             :         {
     568           0 :             XSetFunction( pDisp_, pSD->m_aCopyGC, GXcopyInverted );
     569           0 :             pSD->m_aMonoGC = pSD->m_aCopyGC;
     570             :         }
     571             :         else
     572             :         {
     573           0 :             Pixmap hPixmap = XCreatePixmap( pDisp_, pSD->m_aRefWindow, 1, 1, 1 );
     574             :             pSD->m_aMonoGC = XCreateGC( pDisp_,
     575             :                                        hPixmap,
     576             :                                        GCGraphicsExposures,
     577           0 :                                        &values );
     578           0 :             XFreePixmap( pDisp_, hPixmap );
     579             :         }
     580             :         pSD->m_hInvert50 = XCreateBitmapFromData( pDisp_,
     581             :                                                  pSD->m_aRefWindow,
     582             :                                                  reinterpret_cast<const char*>(invert50_bits),
     583             :                                                  invert50_width,
     584           0 :                                                  invert50_height );
     585             :     }
     586           0 :     return pSD;
     587             : }
     588             : 
     589             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     590           0 : void SalDisplay::Init()
     591             : {
     592           0 :     for( size_t i = 0; i < POINTER_COUNT; i++ )
     593           0 :         aPointerCache_[i] = None;
     594             : 
     595           0 :     mpFactory           = (AttributeProvider*)NULL;
     596           0 :     m_bXinerama         = false;
     597             : 
     598           0 :     int nDisplayScreens = ScreenCount( pDisp_ );
     599           0 :     m_aScreens = std::vector<ScreenData>(nDisplayScreens);
     600             : 
     601           0 :     mbExactResolution = false;
     602             :     /*  #i15507#
     603             :      *  Xft resolution should take precedence since
     604             :      *  it is what modern desktops use.
     605             :      */
     606           0 :     const char* pValStr = XGetDefault( pDisp_, "Xft", "dpi" );
     607           0 :     if( pValStr != NULL )
     608             :     {
     609           0 :         const rtl::OString aValStr( pValStr );
     610           0 :         const long nDPI = (long) aValStr.toDouble();
     611             :         // guard against insane resolution
     612           0 :         if( (nDPI >= 50) && (nDPI <= 500) )
     613             :         {
     614           0 :             aResolution_ = Pair( nDPI, nDPI );
     615           0 :             mbExactResolution = true;
     616           0 :         }
     617             :     }
     618           0 :     if( mbExactResolution == false )
     619             :     {
     620             :         aResolution_     =
     621           0 :             Pair( DPI( WidthOfScreen( DefaultScreenOfDisplay( pDisp_ ) ),
     622           0 :                        DisplayWidthMM ( pDisp_, m_nXDefaultScreen.getXScreen() ) ),
     623           0 :                   DPI( HeightOfScreen( DefaultScreenOfDisplay( pDisp_ ) ),
     624           0 :                        DisplayHeightMM( pDisp_, m_nXDefaultScreen.getXScreen() ) ) );
     625             :     }
     626             : 
     627           0 :     nMaxRequestSize_    = XExtendedMaxRequestSize( pDisp_ ) * 4;
     628           0 :     if( !nMaxRequestSize_ )
     629           0 :         nMaxRequestSize_ = XMaxRequestSize( pDisp_ ) * 4;
     630             : 
     631           0 :     SetServerVendor();
     632           0 :     X11SalBitmap::ImplCreateCache();
     633             : 
     634             :     // - - - - - - - - - - Synchronize - - - - - - - - - - - - -
     635           0 :     if( getenv( "SAL_SYNCHRONIZE" ) )
     636           0 :         XSynchronize( pDisp_, True );
     637             : 
     638             :     // - - - - - - - - - - Keyboardmapping - - - - - - - - - - -
     639           0 :     ModifierMapping();
     640             : 
     641             :     // - - - - - - - - - - Window Manager  - - - - - - - - - - -
     642           0 :     m_pWMAdaptor = ::vcl_sal::WMAdaptor::createWMAdaptor( this );
     643             : 
     644           0 :     InitXinerama();
     645             : 
     646             : #ifdef DBG_UTIL
     647             :     PrintInfo();
     648             : #endif
     649           0 : }
     650             : 
     651           0 : void SalX11Display::SetupInput( SalI18N_InputMethod *pInputMethod )
     652             : {
     653           0 :     SetInputMethod( pInputMethod );
     654             : 
     655           0 :     GetGenericData()->ErrorTrapPush();
     656           0 :     SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp_ );
     657           0 :     XSync( pDisp_, False );
     658             : 
     659           0 :     bool bError = GetGenericData()->ErrorTrapPop( false );
     660           0 :     GetGenericData()->ErrorTrapPush();
     661           0 :     pKbdExtension->UseExtension( ! bError );
     662           0 :     GetGenericData()->ErrorTrapPop();
     663             : 
     664           0 :     SetKbdExtension( pKbdExtension );
     665           0 : }
     666             : 
     667             : // Keyboard
     668             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     669             : 
     670             : namespace {
     671             : 
     672           0 : bool InitXkb(Display* dpy)
     673             : {
     674             :     int nOpcode, nEvent, nError;
     675           0 :     int nXkbMajor = XkbMajorVersion;
     676           0 :     int nXkbMinor = XkbMinorVersion;
     677             : 
     678           0 :     if (!XkbLibraryVersion(&nXkbMajor, &nXkbMinor))
     679           0 :         return false;
     680             : 
     681             :     return XkbQueryExtension(
     682           0 :         dpy, &nOpcode, &nEvent, &nError, &nXkbMajor, &nXkbMinor);
     683             : }
     684             : 
     685           0 : unsigned int GetKeySymMask(Display* dpy, KeySym nKeySym)
     686             : {
     687           0 :     int nMask = 0;
     688           0 :     XModifierKeymap* pXmkMap = XGetModifierMapping(dpy);
     689           0 :     KeyCode nKeyCode = XKeysymToKeycode(dpy, nKeySym);
     690           0 :     if (nKeyCode == NoSymbol)
     691           0 :         return 0;
     692             : 
     693           0 :     for (int i = 0; i < 8; ++i)
     694             :     {
     695           0 :         KeyCode nThisKeyCode = pXmkMap->modifiermap[pXmkMap->max_keypermod*i];
     696           0 :         if (nThisKeyCode == nKeyCode)
     697           0 :             nMask = 1 << i;
     698             :     }
     699           0 :     XFreeModifiermap(pXmkMap);
     700           0 :     return nMask;
     701             : }
     702             : 
     703             : }
     704             : 
     705           0 : void SalDisplay::SimulateKeyPress( sal_uInt16 nKeyCode )
     706             : {
     707           0 :     if (nKeyCode == KEY_CAPSLOCK)
     708             :     {
     709           0 :         Display* dpy = GetDisplay();
     710           0 :         if (!InitXkb(dpy))
     711           0 :             return;
     712             : 
     713           0 :         unsigned int nMask = GetKeySymMask(dpy, XK_Caps_Lock);
     714             :         XkbStateRec xkbState;
     715           0 :         XkbGetState(dpy, XkbUseCoreKbd, &xkbState);
     716           0 :         unsigned int nCapsLockState = xkbState.locked_mods & nMask;
     717           0 :         if (nCapsLockState)
     718           0 :             XkbLockModifiers (dpy, XkbUseCoreKbd, nMask, 0);
     719             :         else
     720           0 :             XkbLockModifiers (dpy, XkbUseCoreKbd, nMask, nMask);
     721             :     }
     722             : }
     723             : 
     724           0 : sal_uInt16 SalDisplay::GetIndicatorState() const
     725             : {
     726           0 :     unsigned int _state = 0;
     727           0 :     sal_uInt16 nState = 0;
     728           0 :     XkbGetIndicatorState(pDisp_, XkbUseCoreKbd, &_state);
     729             : 
     730           0 :     if ((_state & 0x00000001))
     731           0 :         nState |= INDICATOR_CAPSLOCK;
     732           0 :     if ((_state & 0x00000002))
     733           0 :         nState |= INDICATOR_NUMLOCK;
     734           0 :     if ((_state & 0x00000004))
     735           0 :         nState |= INDICATOR_SCROLLLOCK;
     736             : 
     737           0 :     return nState;
     738             : }
     739             : 
     740           0 : rtl::OUString SalDisplay::GetKeyNameFromKeySym( KeySym nKeySym ) const
     741             : {
     742           0 :     rtl::OUString aLang = Application::GetSettings().GetUILanguageTag().getLanguage();
     743           0 :     rtl::OUString aRet;
     744             : 
     745             :     // return an empty string for keysyms that are not bound to
     746             :     // any key code
     747           0 :     XLIB_KeyCode aKeyCode = XKeysymToKeycode( GetDisplay(), nKeySym );
     748           0 :     if( aKeyCode != 0 && aKeyCode != NoSymbol )
     749             :     {
     750           0 :         if( !nKeySym )
     751           0 :             aRet = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "???" ) );
     752             :         else
     753             :         {
     754           0 :             aRet = ::vcl_sal::getKeysymReplacementName( aLang, nKeySym );
     755           0 :             if( aRet.isEmpty() )
     756             :             {
     757           0 :                 const char *pString = XKeysymToString( nKeySym );
     758           0 :                 int n = strlen( pString );
     759           0 :                 if( n > 2 && pString[n-2] == '_' )
     760           0 :                     aRet = rtl::OUString( pString, n-2, RTL_TEXTENCODING_ISO_8859_1 );
     761             :                 else
     762           0 :                     aRet = rtl::OUString( pString, n, RTL_TEXTENCODING_ISO_8859_1 );
     763             :             }
     764             :         }
     765             :     }
     766           0 :     return aRet;
     767             : }
     768             : 
     769           0 : inline KeySym sal_XModifier2Keysym( Display         *pDisplay,
     770             :                                     XModifierKeymap *pXModMap,
     771             :                                     int              n )
     772             : {
     773             :     return XkbKeycodeToKeysym( pDisplay,
     774           0 :                              pXModMap->modifiermap[n*pXModMap->max_keypermod],
     775           0 :                              0,0 );
     776             : }
     777             : 
     778           0 : void SalDisplay::ModifierMapping()
     779             : {
     780           0 :     XModifierKeymap *pXModMap = XGetModifierMapping( pDisp_ );
     781             : 
     782           0 :     bNumLockFromXS_ = True;
     783           0 :     nShiftKeySym_   = sal_XModifier2Keysym( pDisp_, pXModMap, ShiftMapIndex );
     784           0 :     nCtrlKeySym_    = sal_XModifier2Keysym( pDisp_, pXModMap, ControlMapIndex );
     785           0 :     nMod1KeySym_    = sal_XModifier2Keysym( pDisp_, pXModMap, Mod1MapIndex );
     786             :     // Auf Sun-Servern und SCO-Severn beruecksichtigt XLookupString
     787             :     // nicht den NumLock Modifier.
     788           0 :     if( GetServerVendor() == vendor_sun )
     789             :     {
     790           0 :         XLIB_KeyCode aNumLock = XKeysymToKeycode( pDisp_, XK_Num_Lock );
     791             : 
     792           0 :         if( aNumLock ) for( int i = ShiftMapIndex; i <= Mod5MapIndex; i++ )
     793             :         {
     794           0 :             if( pXModMap->modifiermap[i*pXModMap->max_keypermod] == aNumLock )
     795             :             {
     796           0 :                 bNumLockFromXS_ = False;
     797           0 :                 nNumLockIndex_  = i;
     798           0 :                 nNumLockMask_   = 1<<i;
     799           0 :                 break;
     800             :             }
     801             :         }
     802             :     }
     803             : 
     804           0 :     XFreeModifiermap( pXModMap );
     805           0 : }
     806             : 
     807             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
     808           0 : rtl::OUString SalDisplay::GetKeyName( sal_uInt16 nKeyCode ) const
     809             : {
     810           0 :     String aStrMap;
     811           0 :     String aCustomKeyName;
     812             : 
     813           0 :     if( nKeyCode & KEY_MOD1 )
     814           0 :         aStrMap += GetKeyNameFromKeySym( nCtrlKeySym_ );
     815             : 
     816           0 :     if( nKeyCode & KEY_MOD2 )
     817             :     {
     818           0 :         if( aStrMap.Len() )
     819           0 :             aStrMap += '+';
     820           0 :         aStrMap += GetKeyNameFromKeySym( nMod1KeySym_ );
     821             :     }
     822             : 
     823           0 :     if( nKeyCode & KEY_SHIFT )
     824             :     {
     825           0 :         if( aStrMap.Len() )
     826           0 :             aStrMap += '+';
     827           0 :         aStrMap += GetKeyNameFromKeySym( nShiftKeySym_ );
     828             :     }
     829           0 :     nKeyCode &= 0x0FFF;
     830             : 
     831           0 :     KeySym nKeySym = 0;
     832             : 
     833           0 :     if( KEY_0 <= nKeyCode && nKeyCode <= KEY_9 )
     834           0 :         nKeySym = XK_0 + (nKeyCode - KEY_0);
     835           0 :     else if( KEY_A <= nKeyCode && nKeyCode <= KEY_Z )
     836           0 :         nKeySym = XK_A + (nKeyCode - KEY_A);
     837           0 :     else if( KEY_F1 <= nKeyCode && nKeyCode <= KEY_F26 ) // Existiert die Taste
     838           0 :         nKeySym = XK_F1 + (nKeyCode - KEY_F1);
     839           0 :     else switch( nKeyCode )
     840             :     {
     841             :         case KEY_DOWN:
     842           0 :             nKeySym = XK_Down;
     843           0 :             break;
     844             :         case KEY_UP:
     845           0 :             nKeySym = XK_Up;
     846           0 :             break;
     847             :         case KEY_LEFT:
     848           0 :             nKeySym = XK_Left;
     849           0 :             break;
     850             :         case KEY_RIGHT:
     851           0 :             nKeySym = XK_Right;
     852           0 :             break;
     853             :         case KEY_HOME:
     854           0 :             nKeySym = XK_Home;
     855           0 :             break;
     856             :         case KEY_END:
     857           0 :             nKeySym = XK_End;
     858           0 :             break;
     859             :         case KEY_PAGEUP:
     860           0 :             nKeySym = XK_Prior;
     861           0 :             break;
     862             :         case KEY_PAGEDOWN:
     863           0 :             nKeySym = XK_Next;
     864           0 :             break;
     865             :         case KEY_RETURN:
     866           0 :             nKeySym = XK_Return;
     867           0 :             break;
     868             :         case KEY_ESCAPE:
     869           0 :             nKeySym = XK_Escape;
     870           0 :             break;
     871             :         case KEY_TAB:
     872           0 :             nKeySym = XK_Tab;
     873           0 :             break;
     874             :         case KEY_BACKSPACE:
     875           0 :             nKeySym = XK_BackSpace;
     876           0 :             break;
     877             :         case KEY_SPACE:
     878           0 :             nKeySym = XK_space;
     879           0 :             break;
     880             :         case KEY_INSERT:
     881           0 :             nKeySym = XK_Insert;
     882           0 :             break;
     883             :         case KEY_DELETE:
     884           0 :             nKeySym = XK_Delete;
     885           0 :             break;
     886             : 
     887             :         #if !defined (SunXK_Undo)
     888             :             #define SunXK_Stop      0x0000FF69  // XK_Cancel
     889             :             #define SunXK_Props     0x1005FF70
     890             :             #define SunXK_Front     0x1005FF71
     891             :             #define SunXK_Copy      0x1005FF72
     892             :             #define SunXK_Open      0x1005FF73
     893             :             #define SunXK_Paste     0x1005FF74
     894             :             #define SunXK_Cut       0x1005FF75
     895             :         #endif
     896             : 
     897             :         case KEY_REPEAT:
     898           0 :             nKeySym = XK_Redo;
     899           0 :             break;
     900             :         case KEY_PROPERTIES:
     901           0 :             nKeySym = SunXK_Props;
     902           0 :             break;
     903             :         case KEY_UNDO:
     904           0 :             nKeySym = XK_Undo;
     905           0 :             break;
     906             :         case KEY_FRONT:
     907           0 :             nKeySym = SunXK_Front;
     908           0 :             break;
     909             :         case KEY_COPY:
     910           0 :             nKeySym = SunXK_Copy;
     911           0 :             break;
     912             :         case KEY_OPEN:
     913           0 :             nKeySym = SunXK_Open;
     914           0 :             break;
     915             :         case KEY_PASTE:
     916           0 :             nKeySym = SunXK_Paste;
     917           0 :             break;
     918             :         case KEY_FIND:
     919           0 :             nKeySym = XK_Find;
     920           0 :             break;
     921             :         case KEY_CUT:
     922           0 :             nKeySym = GetServerVendor() == vendor_sun ? SunXK_Cut   : XK_L10;
     923           0 :             break;
     924             :         case KEY_ADD:
     925           0 :             aCustomKeyName = '+';
     926           0 :             break;
     927             :         case KEY_SUBTRACT:
     928           0 :             aCustomKeyName = '-';
     929           0 :             break;
     930             :         case KEY_MULTIPLY:
     931           0 :             nKeySym = XK_asterisk;
     932           0 :             break;
     933             :         case KEY_DIVIDE:
     934           0 :             nKeySym = XK_slash;
     935           0 :             break;
     936             :         case KEY_POINT:
     937           0 :             aCustomKeyName = '.';
     938           0 :             break;
     939             :         case KEY_COMMA:
     940           0 :             nKeySym = XK_comma;
     941           0 :             break;
     942             :         case KEY_LESS:
     943           0 :             nKeySym = XK_less;
     944           0 :             break;
     945             :         case KEY_GREATER:
     946           0 :             nKeySym = XK_greater;
     947           0 :             break;
     948             :         case KEY_EQUAL:
     949           0 :             nKeySym = XK_equal;
     950           0 :             break;
     951             :         case KEY_HELP:
     952           0 :             nKeySym = XK_Help;
     953           0 :             break;
     954             :         case KEY_HANGUL_HANJA:
     955           0 :             nKeySym = XK_Hangul_Hanja;
     956           0 :             break;
     957             :         case KEY_TILDE:
     958           0 :             nKeySym = XK_asciitilde;
     959           0 :             break;
     960             :         case KEY_QUOTELEFT:
     961           0 :             nKeySym = XK_grave;
     962           0 :             break;
     963             :         case KEY_BRACKETLEFT:
     964           0 :             aCustomKeyName = '[';
     965           0 :             break;
     966             :         case KEY_BRACKETRIGHT:
     967           0 :             aCustomKeyName = ']';
     968           0 :             break;
     969             :         case KEY_SEMICOLON:
     970           0 :             aCustomKeyName = ';';
     971           0 :             break;
     972             : 
     973             :         default:
     974           0 :             nKeySym = 0;
     975           0 :             break;
     976             :     }
     977             : 
     978           0 :     if( nKeySym )
     979             :     {
     980           0 :         String aKeyName = GetKeyNameFromKeySym( nKeySym );
     981           0 :         if( aKeyName.Len() )
     982             :         {
     983           0 :             if( aStrMap.Len() )
     984           0 :                 aStrMap += '+';
     985           0 :             aStrMap += aKeyName;
     986             :         }
     987             :         else
     988           0 :             aStrMap.Erase();
     989             :     }
     990           0 :     else if (aCustomKeyName.Len())
     991             :     {
     992             :         // For semicolumn, bracket left and bracket right, it's better to use
     993             :         // their keys than their names. (fdo#32891)
     994           0 :         if (aStrMap.Len())
     995           0 :             aStrMap += '+';
     996           0 :         aStrMap += aCustomKeyName;
     997             :     }
     998             :     else
     999           0 :         aStrMap.Erase();
    1000             : 
    1001           0 :     return aStrMap;
    1002             : }
    1003             : 
    1004             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    1005             : #ifndef IsISOKey
    1006             : #define IsISOKey( n ) (0x0000FE00==((n)&0xFFFFFF00))
    1007             : #endif
    1008             : 
    1009           0 : sal_uInt16 SalDisplay::GetKeyCode( KeySym keysym, char*pcPrintable ) const
    1010             : {
    1011           0 :     sal_uInt16 nKey = 0;
    1012             : 
    1013           0 :     if( XK_a <= keysym && XK_z >= keysym )
    1014           0 :         nKey = (sal_uInt16)(KEY_A + (keysym - XK_a));
    1015           0 :     else if( XK_A <= keysym && XK_Z >= keysym )
    1016           0 :         nKey = (sal_uInt16)(KEY_A + (keysym - XK_A));
    1017           0 :     else if( XK_0 <= keysym && XK_9 >= keysym )
    1018           0 :         nKey = (sal_uInt16)(KEY_0 + (keysym - XK_0));
    1019           0 :     else if( IsModifierKey( keysym ) )
    1020             :         ;
    1021           0 :     else if( IsKeypadKey( keysym ) )
    1022             :     {
    1023           0 :         if( (keysym >= XK_KP_0) && (keysym <= XK_KP_9) )
    1024             :         {
    1025           0 :             nKey = (sal_uInt16)(KEY_0 + (keysym - XK_KP_0));
    1026           0 :             *pcPrintable = '0' + nKey - KEY_0;
    1027             :         }
    1028           0 :         else if( IsPFKey( keysym ) )
    1029           0 :             nKey = (sal_uInt16)(KEY_F1 + (keysym - XK_KP_F1));
    1030           0 :         else switch( keysym )
    1031             :         {
    1032             :             case XK_KP_Space:
    1033           0 :                 nKey = KEY_SPACE;
    1034           0 :                 *pcPrintable = ' ';
    1035           0 :                 break;
    1036             :             case XK_KP_Tab:
    1037           0 :                 nKey = KEY_TAB;
    1038           0 :                 break;
    1039             :             case XK_KP_Enter:
    1040           0 :                 nKey = KEY_RETURN;
    1041           0 :                 break;
    1042             :             case XK_KP_Begin:
    1043             :             case XK_KP_Home:
    1044           0 :                 nKey = KEY_HOME;
    1045           0 :                 break;
    1046             :             case XK_KP_Left:
    1047           0 :                 nKey = KEY_LEFT;
    1048           0 :                 break;
    1049             :             case XK_KP_Up:
    1050           0 :                 nKey = KEY_UP;
    1051           0 :                 break;
    1052             :             case XK_KP_Right:
    1053           0 :                 nKey = KEY_RIGHT;
    1054           0 :                 break;
    1055             :             case XK_KP_Down:
    1056           0 :                 nKey = KEY_DOWN;
    1057           0 :                 break;
    1058             :             case XK_KP_Prior: // XK_KP_Page_Up
    1059           0 :                 nKey = KEY_PAGEUP;
    1060           0 :                 break;
    1061             :             case XK_KP_Next: // XK_KP_Page_Down
    1062           0 :                 nKey = KEY_PAGEDOWN;
    1063           0 :                 break;
    1064             :             case XK_KP_End:
    1065           0 :                 nKey = KEY_END;
    1066           0 :                 break;
    1067             :             case XK_KP_Insert:
    1068           0 :                 nKey = KEY_INSERT;
    1069           0 :                 break;
    1070             :             case XK_KP_Delete:
    1071           0 :                 nKey = KEY_DELETE;
    1072           0 :                 break;
    1073             :             case XK_KP_Equal:
    1074           0 :                 nKey = KEY_EQUAL;
    1075           0 :                 *pcPrintable = '=';
    1076           0 :                 break;
    1077             :             case XK_KP_Multiply:
    1078           0 :                 nKey = KEY_MULTIPLY;
    1079           0 :                 *pcPrintable = '*';
    1080           0 :                 break;
    1081             :             case XK_KP_Add:
    1082           0 :                 nKey = KEY_ADD;
    1083           0 :                 *pcPrintable = '+';
    1084           0 :                 break;
    1085             :             case XK_KP_Separator:
    1086           0 :                 nKey = KEY_DECIMAL;
    1087           0 :                 *pcPrintable = ',';
    1088           0 :                 break;
    1089             :             case XK_KP_Subtract:
    1090           0 :                 nKey = KEY_SUBTRACT;
    1091           0 :                 *pcPrintable = '-';
    1092           0 :                 break;
    1093             :             case XK_KP_Decimal:
    1094           0 :                 nKey = KEY_DECIMAL;
    1095           0 :                 *pcPrintable = '.';
    1096           0 :                 break;
    1097             :             case XK_KP_Divide:
    1098           0 :                 nKey = KEY_DIVIDE;
    1099           0 :                 *pcPrintable = '/';
    1100           0 :                 break;
    1101             :         }
    1102             :     }
    1103           0 :     else if( IsFunctionKey( keysym ) )
    1104             :     {
    1105           0 :         if( bNumLockFromXS_ )
    1106             :         {
    1107           0 :             if( keysym >= XK_F1 && keysym <= XK_F26 )
    1108           0 :                 nKey = (sal_uInt16)(KEY_F1 + keysym - XK_F1);
    1109             :         }
    1110           0 :         else switch( keysym )
    1111             :         {
    1112             :             // - - - - - Sun X-Server Tastatur ohne Cursorblock ??? - - -
    1113             :             case XK_R7: // XK_F27:
    1114           0 :                 nKey = KEY_HOME;
    1115           0 :                 break;
    1116             :             case XK_R8: // XK_F28:
    1117           0 :                 nKey = KEY_UP;
    1118           0 :                 break;
    1119             :             case XK_R9: // XK_F29:
    1120           0 :                 nKey = KEY_PAGEUP;
    1121           0 :                 break;
    1122             :             case XK_R10: // XK_F30:
    1123           0 :                 nKey = KEY_LEFT;
    1124           0 :                 break;
    1125             :             case XK_R11: // XK_F31:
    1126           0 :                 nKey = 0; // KEY_F31
    1127           0 :                 break;
    1128             :             case XK_R12: // XK_F32:
    1129           0 :                 nKey = KEY_RIGHT;
    1130           0 :                 break;
    1131             :             case XK_R13: // XK_F33:
    1132           0 :                 nKey = KEY_END;
    1133           0 :                 break;
    1134             :             case XK_R14: // XK_F34:
    1135           0 :                 nKey = KEY_DOWN;
    1136           0 :                 break;
    1137             :             case XK_R15: // XK_F35:
    1138           0 :                 nKey = KEY_PAGEDOWN;
    1139           0 :                 break;
    1140             :             // - - - - - Sun X-Server Tastatur ??? - - - - - - - - - - - -
    1141             :             case XK_L1: // XK_F11:
    1142           0 :                 nKey = KEY_F11; // on a sun keyboard this actually is usally SunXK_Stop,
    1143             :                 // but VCL doesn't have a key defintion for that
    1144           0 :                 break;
    1145             :             case XK_L2: // XK_F12:
    1146           0 :                 if ( GetServerVendor() == vendor_sun )
    1147           0 :                     nKey = KEY_REPEAT;
    1148             :                 else
    1149           0 :                     nKey = KEY_F12;
    1150           0 :                 break;
    1151             :             case XK_L3: // XK_F13:
    1152           0 :                 nKey = KEY_PROPERTIES; // KEY_F13
    1153           0 :                 break;
    1154             :             case XK_L4: // XK_F14:
    1155           0 :                 nKey = KEY_UNDO; // KEY_F14
    1156           0 :                 break;
    1157             :             case XK_L5: // XK_F15:
    1158           0 :                 nKey = KEY_F15; // KEY_FRONT
    1159           0 :                 break;
    1160             :             case XK_L6: // XK_F16:
    1161           0 :                 nKey = KEY_COPY; // KEY_F16
    1162           0 :                 break;
    1163             :             case XK_L7: // XK_F17:
    1164           0 :                 nKey = KEY_F17; // KEY_OPEN
    1165           0 :                 break;
    1166             :             case XK_L8: // XK_F18:
    1167           0 :                 nKey = KEY_PASTE; // KEY_F18
    1168           0 :                 break;
    1169             :             case XK_L9: // XK_F19:
    1170           0 :                 nKey = KEY_F19; // KEY_FIND
    1171           0 :                 break;
    1172             :             case XK_L10: // XK_F20:
    1173           0 :                 nKey = KEY_CUT; // KEY_F20
    1174           0 :                 break;
    1175             :             default:
    1176           0 :                 if( keysym >= XK_F1 && keysym <= XK_F26 )
    1177           0 :                     nKey = (sal_uInt16)(KEY_F1 + keysym - XK_F1);
    1178           0 :                 break;
    1179             :         }
    1180             :     }
    1181           0 :     else if( IsCursorKey( keysym ) )
    1182             :     {
    1183           0 :         switch( keysym )
    1184             :         {
    1185             :             case XK_Begin:
    1186             :             case XK_Home:
    1187           0 :                 nKey = KEY_HOME;
    1188           0 :                 break;
    1189             :             case XK_Left:
    1190           0 :                 nKey = KEY_LEFT;
    1191           0 :                 break;
    1192             :             case XK_Up:
    1193           0 :                 nKey = KEY_UP;
    1194           0 :                 break;
    1195             :             case XK_Right:
    1196           0 :                 nKey = KEY_RIGHT;
    1197           0 :                 break;
    1198             :             case XK_Down:
    1199           0 :                 nKey = KEY_DOWN;
    1200           0 :                 break;
    1201             :             case XK_Prior: // XK_Page_Up
    1202           0 :                 nKey = KEY_PAGEUP;
    1203           0 :                 break;
    1204             :             case XK_Next: // XK_Page_Down
    1205           0 :                 nKey = KEY_PAGEDOWN;
    1206           0 :                 break;
    1207             :             case XK_End:
    1208           0 :                 nKey = KEY_END;
    1209           0 :                 break;
    1210             :         }
    1211             :     }
    1212           0 :     else if( IsMiscFunctionKey( keysym ) )
    1213             :     {
    1214           0 :         switch( keysym )
    1215             :         {
    1216             :             case XK_Insert:
    1217           0 :                 nKey = KEY_INSERT;
    1218           0 :                 break;
    1219             :             case XK_Redo:
    1220           0 :                 nKey = KEY_REPEAT;
    1221           0 :                 break;
    1222             :             case XK_Undo:
    1223           0 :                 nKey = KEY_UNDO;
    1224           0 :                 break;
    1225             :             case XK_Find:
    1226           0 :                 nKey = KEY_FIND;
    1227           0 :                 break;
    1228             :             case XK_Help:
    1229           0 :                 nKey = KEY_HELP;
    1230           0 :                 break;
    1231             :             case XK_Menu:
    1232           0 :                 nKey = KEY_CONTEXTMENU;
    1233           0 :                 break;
    1234             :         }
    1235             :     }
    1236           0 :     else if( IsISOKey( keysym ) )  // XK_ISO_
    1237             :     {
    1238           0 :         switch( keysym )
    1239             :         {
    1240             :             case 0xFE20: // XK_ISO_Left_Tab:
    1241           0 :                 nKey = KEY_TAB;
    1242           0 :                 break;
    1243             :         }
    1244             :     }
    1245           0 :     else switch( keysym )
    1246             :     {
    1247             :         case XK_Return:
    1248           0 :             nKey = KEY_RETURN;
    1249           0 :             break;
    1250             :         case XK_BackSpace:
    1251           0 :             nKey = KEY_BACKSPACE;
    1252           0 :             break;
    1253             :         case XK_Delete:
    1254           0 :             nKey = KEY_DELETE;
    1255           0 :             break;
    1256             :         case XK_space:
    1257           0 :             nKey = KEY_SPACE;
    1258           0 :             break;
    1259             :         case XK_Tab:
    1260           0 :             nKey = KEY_TAB;
    1261           0 :             break;
    1262             :         case XK_Escape:
    1263           0 :             nKey = KEY_ESCAPE;
    1264           0 :             break;
    1265             :         case XK_plus:
    1266           0 :             nKey = KEY_ADD;
    1267           0 :             break;
    1268             :         case XK_minus:
    1269           0 :             nKey = KEY_SUBTRACT;
    1270           0 :             break;
    1271             :         case XK_asterisk:
    1272           0 :             nKey = KEY_MULTIPLY;
    1273           0 :             break;
    1274             :         case XK_slash:
    1275           0 :             nKey = KEY_DIVIDE;
    1276           0 :             break;
    1277             :         case XK_period:
    1278           0 :             nKey = KEY_POINT;
    1279           0 :             *pcPrintable = '.';
    1280           0 :             break;
    1281             :         case XK_comma:
    1282           0 :             nKey = KEY_COMMA;
    1283           0 :             break;
    1284             :         case XK_less:
    1285           0 :             nKey = KEY_LESS;
    1286           0 :             break;
    1287             :         case XK_greater:
    1288           0 :             nKey = KEY_GREATER;
    1289           0 :             break;
    1290             :         case XK_equal:
    1291           0 :             nKey = KEY_EQUAL;
    1292           0 :             break;
    1293             :         case XK_Hangul_Hanja:
    1294           0 :             nKey = KEY_HANGUL_HANJA;
    1295           0 :             break;
    1296             :         case XK_asciitilde:
    1297           0 :             nKey = KEY_TILDE;
    1298           0 :             *pcPrintable = '~';
    1299           0 :             break;
    1300             :         case XK_grave:
    1301           0 :             nKey = KEY_QUOTELEFT;
    1302           0 :             *pcPrintable = '`';
    1303           0 :             break;
    1304             :         case XK_bracketleft:
    1305           0 :             nKey = KEY_BRACKETLEFT;
    1306           0 :             *pcPrintable = '[';
    1307           0 :             break;
    1308             :          case XK_bracketright:
    1309           0 :              nKey = KEY_BRACKETRIGHT;
    1310           0 :              *pcPrintable = ']';
    1311           0 :              break;
    1312             :         case XK_semicolon:
    1313           0 :             nKey = KEY_SEMICOLON;
    1314           0 :             *pcPrintable = ';';
    1315           0 :             break;
    1316             :         // - - - - - - - - - - - - -  Apollo - - - - - - - - - - - - - 0x1000
    1317             :         case 0x1000FF02: // apXK_Copy
    1318           0 :             nKey = KEY_COPY;
    1319           0 :             break;
    1320             :         case 0x1000FF03: // apXK_Cut
    1321           0 :             nKey = KEY_CUT;
    1322           0 :             break;
    1323             :         case 0x1000FF04: // apXK_Paste
    1324           0 :             nKey = KEY_PASTE;
    1325           0 :             break;
    1326             :         case 0x1000FF14: // apXK_Repeat
    1327           0 :             nKey = KEY_REPEAT;
    1328           0 :             break;
    1329             :         // Exit, Save
    1330             :         // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000
    1331             :         case 0x1000FF00:
    1332           0 :             nKey = KEY_DELETE;
    1333           0 :             break;
    1334             :         // - - - - - - - - - - - - - -  H P  - - - - - - - - - - - - - 0x1000
    1335             :         case 0x1000FF73: // hpXK_DeleteChar
    1336           0 :             nKey = KEY_DELETE;
    1337           0 :             break;
    1338             :         case 0x1000FF74: // hpXK_BackTab
    1339             :         case 0x1000FF75: // hpXK_KP_BackTab
    1340           0 :             nKey = KEY_TAB;
    1341           0 :             break;
    1342             :         // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - -
    1343             :         // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004
    1344             :         case 0x1004FF02: // osfXK_Copy
    1345           0 :             nKey = KEY_COPY;
    1346           0 :             break;
    1347             :         case 0x1004FF03: // osfXK_Cut
    1348           0 :             nKey = KEY_CUT;
    1349           0 :             break;
    1350             :         case 0x1004FF04: // osfXK_Paste
    1351           0 :             nKey = KEY_PASTE;
    1352           0 :             break;
    1353             :         case 0x1004FF07: // osfXK_BackTab
    1354           0 :             nKey = KEY_TAB;
    1355           0 :             break;
    1356             :         case 0x1004FF08: // osfXK_BackSpace
    1357           0 :             nKey = KEY_BACKSPACE;
    1358           0 :             break;
    1359             :         case 0x1004FF1B: // osfXK_Escape
    1360           0 :             nKey = KEY_ESCAPE;
    1361           0 :             break;
    1362             :         // Up, Down, Left, Right, PageUp, PageDown
    1363             :         // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - -
    1364             :         // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007
    1365             :         // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - -
    1366             :         // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005
    1367             :         case 0x1005FF10: // SunXK_F36
    1368           0 :             nKey = KEY_F11;
    1369           0 :             break;
    1370             :         case 0x1005FF11: // SunXK_F37
    1371           0 :             nKey = KEY_F12;
    1372           0 :             break;
    1373             :         case 0x1005FF70: // SunXK_Props
    1374           0 :             nKey = KEY_PROPERTIES;
    1375           0 :             break;
    1376             :         case 0x1005FF71: // SunXK_Front
    1377           0 :             nKey = KEY_FRONT;
    1378           0 :             break;
    1379             :         case 0x1005FF72: // SunXK_Copy
    1380           0 :             nKey = KEY_COPY;
    1381           0 :             break;
    1382             :         case 0x1005FF73: // SunXK_Open
    1383           0 :             nKey = KEY_OPEN;
    1384           0 :             break;
    1385             :         case 0x1005FF74: // SunXK_Paste
    1386           0 :             nKey = KEY_PASTE;
    1387           0 :             break;
    1388             :         case 0x1005FF75: // SunXK_Cut
    1389           0 :             nKey = KEY_CUT;
    1390           0 :             break;
    1391             :     }
    1392           0 :     return nKey;
    1393             : }
    1394             : 
    1395             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    1396           0 : KeySym SalDisplay::GetKeySym( XKeyEvent        *pEvent,
    1397             :                                     unsigned char    *pPrintable,
    1398             :                                     int              *pLen,
    1399             :                                     KeySym           *pUnmodifiedKeySym,
    1400             :                                     Status           *pStatusReturn,
    1401             :                                     XIC              aInputContext ) const
    1402             : {
    1403           0 :     KeySym nKeySym = 0;
    1404           0 :     memset( pPrintable, 0, *pLen );
    1405           0 :     *pStatusReturn = 0;
    1406             : 
    1407             :     // first get the printable of the possibly modified KeySym
    1408           0 :     if (   (aInputContext == 0)
    1409             :         || (pEvent->type == KeyRelease)
    1410           0 :         || (mpInputMethod != NULL && mpInputMethod->PosixLocale()) )
    1411             :     {
    1412             :         // XmbLookupString must not be called for KeyRelease events
    1413             :         // Cannot enter space in c locale problem #89616# #88978# btraq #4478197
    1414           0 :         *pLen = XLookupString( pEvent, (char*)pPrintable, 1, &nKeySym, NULL );
    1415             :     }
    1416             :     else
    1417             :     {
    1418             :         *pLen = XmbLookupString( aInputContext,
    1419           0 :                         pEvent, (char*)pPrintable, *pLen - 1, &nKeySym, pStatusReturn );
    1420             : 
    1421             :         // Lookup the string again, now with appropriate size
    1422           0 :         if ( *pStatusReturn == XBufferOverflow )
    1423             :         {
    1424           0 :             pPrintable[ 0 ] = (char)0;
    1425           0 :             return 0;
    1426             :         }
    1427             : 
    1428           0 :         switch ( *pStatusReturn )
    1429             :         {
    1430             :             case XBufferOverflow:
    1431             :                 /* unhandled error */
    1432           0 :                 break;
    1433             :             case XLookupNone:
    1434             :                 /* unhandled error */
    1435           0 :                 break;
    1436             :             case XLookupKeySym:
    1437             :                 /* this is a strange one: on exceed sometimes
    1438             :                  * no printable is returned for the first char entered,
    1439             :                  * just to retry lookup solves the problem. The problem
    1440             :                  * is not yet fully understood, so restrict 2nd lookup
    1441             :                  * to 7bit ascii chars */
    1442           0 :                 if ( (XK_space <= nKeySym) && (XK_asciitilde >= nKeySym) )
    1443             :                 {
    1444           0 :                     *pLen = 1;
    1445           0 :                     pPrintable[ 0 ] = (char)nKeySym;
    1446             :                 }
    1447           0 :                 break;
    1448             :             case XLookupBoth:
    1449             :             case XLookupChars:
    1450             : 
    1451             :                 /* nothing to, char allready in pPrintable */
    1452           0 :                 break;
    1453             :         }
    1454             :     }
    1455             : 
    1456           0 :     if( !bNumLockFromXS_
    1457             :         && (IsCursorKey(nKeySym)
    1458             :             || IsFunctionKey(nKeySym)
    1459             :             || IsKeypadKey(nKeySym)
    1460             :             || XK_Delete == nKeySym ) )
    1461             :     {
    1462             :         // Bei einigen X-Servern muss man bei den Keypadtasten
    1463             :         // schon sehr genau hinschauen. ZB. Solaris XServer:
    1464             :         // 2, 4, 6, 8 werden als Cursorkeys klassifiziert (Up, Down, Left, Right
    1465             :         // 1, 3, 5, 9 werden als Functionkeys klassifiziert (F27,F29,F33,F35)
    1466             :         // 0 als Keypadkey und der Dezimalpunkt gar nicht (KP_Insert)
    1467           0 :         KeySym nNewKeySym = XLookupKeysym( pEvent, nNumLockIndex_ );
    1468           0 :         if( nNewKeySym != NoSymbol )
    1469           0 :             nKeySym = nNewKeySym;
    1470             :     }
    1471             : 
    1472             :     // Now get the unmodified KeySym for KeyCode retrieval
    1473             :     // try to strip off modifiers, e.g. Ctrl-$ becomes Ctrl-Shift-4
    1474           0 :     *pUnmodifiedKeySym  = XkbKeycodeToKeysym( GetDisplay(), pEvent->keycode, 0, 0);
    1475             : 
    1476           0 :     return nKeySym;
    1477             : }
    1478             : 
    1479             : // Pointer
    1480             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    1481             : #define MAKE_BITMAP( name ) \
    1482             :     XCreateBitmapFromData( pDisp_, \
    1483             :                            DefaultRootWindow( pDisp_ ), \
    1484             :                            reinterpret_cast<const char*>(name##_bits), \
    1485             :                            name##_width, \
    1486             :                            name##_height )
    1487             : 
    1488             : #define MAKE_CURSOR( name ) \
    1489             :     aCursBitmap = MAKE_BITMAP( name##curs ); \
    1490             :     aMaskBitmap = MAKE_BITMAP( name##mask ); \
    1491             :     nXHot = name##curs_x_hot; \
    1492             :     nYHot = name##curs_y_hot
    1493             : 
    1494           0 : XLIB_Cursor SalDisplay::GetPointer( int ePointerStyle )
    1495             : {
    1496           0 :     if( ePointerStyle >= POINTER_COUNT )
    1497           0 :         return 0;
    1498             : 
    1499           0 :     XLIB_Cursor &aCur = aPointerCache_[ePointerStyle];
    1500             : 
    1501           0 :     if( aCur != None )
    1502           0 :         return aCur;
    1503             : 
    1504           0 :     Pixmap          aCursBitmap = None, aMaskBitmap = None;
    1505           0 :     unsigned int    nXHot = 0, nYHot = 0;
    1506             : 
    1507           0 :     switch( ePointerStyle )
    1508             :     {
    1509             :         case POINTER_NULL:
    1510           0 :             MAKE_CURSOR( null );
    1511           0 :             break;
    1512             :         case POINTER_ARROW:
    1513           0 :             aCur = XCreateFontCursor( pDisp_, XC_left_ptr );
    1514             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1515           0 :             break;
    1516             :         case POINTER_WAIT:
    1517           0 :             aCur = XCreateFontCursor( pDisp_, XC_watch );
    1518           0 :             break;
    1519             :         case POINTER_TEXT:          // Mouse Pointer ist ein "I" Beam
    1520           0 :             aCur = XCreateFontCursor( pDisp_, XC_xterm );
    1521             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1522           0 :             break;
    1523             :         case POINTER_HELP:
    1524           0 :             aCur = XCreateFontCursor( pDisp_, XC_question_arrow );
    1525             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1526           0 :             break;
    1527             :         case POINTER_CROSS:         // Mouse Pointer ist ein Kreuz
    1528           0 :             aCur = XCreateFontCursor( pDisp_, XC_crosshair );
    1529             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1530           0 :             break;
    1531             :         case POINTER_NSIZE:
    1532           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow );
    1533             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1534           0 :             break;
    1535             :         case POINTER_SSIZE:
    1536           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow );
    1537             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1538           0 :             break;
    1539             :         case POINTER_WSIZE:
    1540           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow );
    1541             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1542           0 :             break;
    1543             :         case POINTER_ESIZE:
    1544           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow );
    1545             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1546           0 :             break;
    1547             :         case POINTER_WINDOW_NSIZE:
    1548           0 :             aCur = XCreateFontCursor( pDisp_, XC_top_side );
    1549             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1550           0 :             break;
    1551             :         case POINTER_WINDOW_SSIZE:
    1552           0 :             aCur = XCreateFontCursor( pDisp_, XC_bottom_side );
    1553             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1554           0 :             break;
    1555             :         case POINTER_WINDOW_WSIZE:
    1556           0 :             aCur = XCreateFontCursor( pDisp_, XC_left_side );
    1557             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1558           0 :             break;
    1559             :         case POINTER_WINDOW_ESIZE:
    1560           0 :             aCur = XCreateFontCursor( pDisp_, XC_right_side );
    1561             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1562           0 :             break;
    1563             :         case POINTER_NWSIZE:
    1564           0 :             aCur = XCreateFontCursor( pDisp_, XC_top_left_corner );
    1565           0 :             break;
    1566             :         case POINTER_NESIZE:
    1567           0 :             aCur = XCreateFontCursor( pDisp_, XC_top_right_corner );
    1568           0 :             break;
    1569             :         case POINTER_SWSIZE:
    1570           0 :             aCur = XCreateFontCursor( pDisp_, XC_bottom_left_corner );
    1571           0 :             break;
    1572             :         case POINTER_SESIZE:
    1573           0 :             aCur = XCreateFontCursor( pDisp_, XC_bottom_right_corner );
    1574           0 :             break;
    1575             :         case POINTER_WINDOW_NWSIZE:
    1576           0 :             aCur = XCreateFontCursor( pDisp_, XC_top_left_corner );
    1577             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1578           0 :             break;
    1579             :         case POINTER_WINDOW_NESIZE:
    1580           0 :             aCur = XCreateFontCursor( pDisp_, XC_top_right_corner );
    1581             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1582           0 :             break;
    1583             :         case POINTER_WINDOW_SWSIZE:
    1584           0 :             aCur = XCreateFontCursor( pDisp_, XC_bottom_left_corner );
    1585             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1586           0 :             break;
    1587             :         case POINTER_WINDOW_SESIZE:
    1588           0 :             aCur = XCreateFontCursor( pDisp_, XC_bottom_right_corner );
    1589             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1590           0 :             break;
    1591             :         case POINTER_HSPLIT:
    1592           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow );
    1593           0 :             break;
    1594             :         case POINTER_VSPLIT:
    1595           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow );
    1596           0 :             break;
    1597             :         case POINTER_HSIZEBAR:
    1598           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_h_double_arrow ); // ???
    1599             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1600           0 :             break;
    1601             :         case POINTER_VSIZEBAR:
    1602           0 :             aCur = XCreateFontCursor( pDisp_, XC_sb_v_double_arrow ); // ???
    1603             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1604           0 :             break;
    1605             :         case POINTER_REFHAND:
    1606           0 :             aCur = XCreateFontCursor( pDisp_, XC_hand1 );
    1607             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1608           0 :             break;
    1609             :         case POINTER_HAND:
    1610           0 :             aCur = XCreateFontCursor( pDisp_, XC_hand2 );
    1611           0 :             break;
    1612             :         case POINTER_MAGNIFY:
    1613           0 :             MAKE_CURSOR( magnify_ );
    1614           0 :             break;
    1615             :         case POINTER_FILL:
    1616           0 :             MAKE_CURSOR( fill_ );
    1617           0 :             break;
    1618             :         case POINTER_MOVE:
    1619           0 :             aCur = XCreateFontCursor( pDisp_, XC_fleur );
    1620           0 :             break;
    1621             :         case POINTER_MOVEDATA:
    1622           0 :             MAKE_CURSOR( movedata_ );
    1623           0 :             break;
    1624             :         case POINTER_COPYDATA:
    1625           0 :             MAKE_CURSOR( copydata_ );
    1626           0 :             break;
    1627             :         case POINTER_MOVEFILE:
    1628           0 :             MAKE_CURSOR( movefile_ );
    1629           0 :             break;
    1630             :         case POINTER_COPYFILE:
    1631           0 :             MAKE_CURSOR( copyfile_ );
    1632           0 :             break;
    1633             :         case POINTER_MOVEFILES:
    1634           0 :             MAKE_CURSOR( movefiles_ );
    1635           0 :             break;
    1636             :         case POINTER_COPYFILES:
    1637           0 :             MAKE_CURSOR( copyfiles_ );
    1638           0 :             break;
    1639             :         case POINTER_NOTALLOWED:
    1640           0 :             MAKE_CURSOR( nodrop_ );
    1641           0 :             break;
    1642             :         case POINTER_ROTATE:
    1643           0 :             MAKE_CURSOR( rotate_ );
    1644           0 :             break;
    1645             :         case POINTER_HSHEAR:
    1646           0 :             MAKE_CURSOR( hshear_ );
    1647           0 :             break;
    1648             :         case POINTER_VSHEAR:
    1649           0 :             MAKE_CURSOR( vshear_ );
    1650           0 :             break;
    1651             :         case POINTER_DRAW_LINE:
    1652           0 :             MAKE_CURSOR( drawline_ );
    1653           0 :             break;
    1654             :         case POINTER_DRAW_RECT:
    1655           0 :             MAKE_CURSOR( drawrect_ );
    1656           0 :             break;
    1657             :         case POINTER_DRAW_POLYGON:
    1658           0 :             MAKE_CURSOR( drawpolygon_ );
    1659           0 :             break;
    1660             :         case POINTER_DRAW_BEZIER:
    1661           0 :             MAKE_CURSOR( drawbezier_ );
    1662           0 :             break;
    1663             :         case POINTER_DRAW_ARC:
    1664           0 :             MAKE_CURSOR( drawarc_ );
    1665           0 :             break;
    1666             :         case POINTER_DRAW_PIE:
    1667           0 :             MAKE_CURSOR( drawpie_ );
    1668           0 :             break;
    1669             :         case POINTER_DRAW_CIRCLECUT:
    1670           0 :             MAKE_CURSOR( drawcirclecut_ );
    1671           0 :             break;
    1672             :         case POINTER_DRAW_ELLIPSE:
    1673           0 :             MAKE_CURSOR( drawellipse_ );
    1674           0 :             break;
    1675             :         case POINTER_DRAW_CONNECT:
    1676           0 :             MAKE_CURSOR( drawconnect_ );
    1677           0 :             break;
    1678             :         case POINTER_DRAW_TEXT:
    1679           0 :             MAKE_CURSOR( drawtext_ );
    1680           0 :             break;
    1681             :         case POINTER_MIRROR:
    1682           0 :             MAKE_CURSOR( mirror_ );
    1683           0 :             break;
    1684             :         case POINTER_CROOK:
    1685           0 :             MAKE_CURSOR( crook_ );
    1686           0 :             break;
    1687             :         case POINTER_CROP:
    1688           0 :             MAKE_CURSOR( crop_ );
    1689           0 :             break;
    1690             :         case POINTER_MOVEPOINT:
    1691           0 :             MAKE_CURSOR( movepoint_ );
    1692           0 :             break;
    1693             :         case POINTER_MOVEBEZIERWEIGHT:
    1694           0 :             MAKE_CURSOR( movebezierweight_ );
    1695           0 :             break;
    1696             :         case POINTER_DRAW_FREEHAND:
    1697           0 :             MAKE_CURSOR( drawfreehand_ );
    1698           0 :             break;
    1699             :         case POINTER_DRAW_CAPTION:
    1700           0 :             MAKE_CURSOR( drawcaption_ );
    1701           0 :             break;
    1702             :         case POINTER_PEN:       // Mouse Pointer ist ein Stift
    1703           0 :             aCur = XCreateFontCursor( pDisp_, XC_pencil );
    1704             :             DBG_ASSERT( aCur != None, "GetPointer: Could not define cursor" );
    1705           0 :             break;
    1706             :         case POINTER_LINKDATA:
    1707           0 :             MAKE_CURSOR( linkdata_ );
    1708           0 :             break;
    1709             :         case POINTER_MOVEDATALINK:
    1710           0 :             MAKE_CURSOR( movedlnk_ );
    1711           0 :             break;
    1712             :         case POINTER_COPYDATALINK:
    1713           0 :             MAKE_CURSOR( copydlnk_ );
    1714           0 :             break;
    1715             :         case POINTER_LINKFILE:
    1716           0 :             MAKE_CURSOR( linkfile_ );
    1717           0 :             break;
    1718             :         case POINTER_MOVEFILELINK:
    1719           0 :             MAKE_CURSOR( moveflnk_ );
    1720           0 :             break;
    1721             :         case POINTER_COPYFILELINK:
    1722           0 :             MAKE_CURSOR( copyflnk_ );
    1723           0 :             break;
    1724             :         case POINTER_CHART:
    1725           0 :             MAKE_CURSOR( chart_ );
    1726           0 :             break;
    1727             :         case POINTER_DETECTIVE:
    1728           0 :             MAKE_CURSOR( detective_ );
    1729           0 :             break;
    1730             :         case POINTER_PIVOT_COL:
    1731           0 :             MAKE_CURSOR( pivotcol_ );
    1732           0 :             break;
    1733             :         case POINTER_PIVOT_ROW:
    1734           0 :             MAKE_CURSOR( pivotrow_ );
    1735           0 :             break;
    1736             :         case POINTER_PIVOT_FIELD:
    1737           0 :             MAKE_CURSOR( pivotfld_ );
    1738           0 :             break;
    1739             :         case POINTER_PIVOT_DELETE:
    1740           0 :             MAKE_CURSOR( pivotdel_ );
    1741           0 :             break;
    1742             :         case POINTER_CHAIN:
    1743           0 :             MAKE_CURSOR( chain_ );
    1744           0 :             break;
    1745             :         case POINTER_CHAIN_NOTALLOWED:
    1746           0 :             MAKE_CURSOR( chainnot_ );
    1747           0 :             break;
    1748             :         case POINTER_TIMEEVENT_MOVE:
    1749           0 :             MAKE_CURSOR( timemove_ );
    1750           0 :             break;
    1751             :         case POINTER_TIMEEVENT_SIZE:
    1752           0 :             MAKE_CURSOR( timesize_ );
    1753           0 :             break;
    1754             :         case POINTER_AUTOSCROLL_N:
    1755           0 :             MAKE_CURSOR(asn_ );
    1756           0 :             break;
    1757             :         case POINTER_AUTOSCROLL_S:
    1758           0 :             MAKE_CURSOR( ass_ );
    1759           0 :             break;
    1760             :         case POINTER_AUTOSCROLL_W:
    1761           0 :             MAKE_CURSOR( asw_ );
    1762           0 :             break;
    1763             :         case POINTER_AUTOSCROLL_E:
    1764           0 :             MAKE_CURSOR( ase_ );
    1765           0 :             break;
    1766             :         case POINTER_AUTOSCROLL_NW:
    1767           0 :             MAKE_CURSOR( asnw_ );
    1768           0 :             break;
    1769             :         case POINTER_AUTOSCROLL_NE:
    1770           0 :             MAKE_CURSOR( asne_ );
    1771           0 :             break;
    1772             :         case POINTER_AUTOSCROLL_SW:
    1773           0 :             MAKE_CURSOR( assw_ );
    1774           0 :             break;
    1775             :         case POINTER_AUTOSCROLL_SE:
    1776           0 :             MAKE_CURSOR( asse_ );
    1777           0 :             break;
    1778             :         case POINTER_AUTOSCROLL_NS:
    1779           0 :             MAKE_CURSOR( asns_ );
    1780           0 :             break;
    1781             :         case POINTER_AUTOSCROLL_WE:
    1782           0 :             MAKE_CURSOR( aswe_ );
    1783           0 :             break;
    1784             :         case POINTER_AUTOSCROLL_NSWE:
    1785           0 :             MAKE_CURSOR( asnswe_ );
    1786           0 :             break;
    1787             :         case POINTER_AIRBRUSH:
    1788           0 :             MAKE_CURSOR( airbrush_ );
    1789           0 :             break;
    1790             :         case POINTER_TEXT_VERTICAL:
    1791           0 :             MAKE_CURSOR( vertcurs_ );
    1792           0 :             break;
    1793             : 
    1794             :         // #i32329# Enhanced table selection
    1795             :         case POINTER_TAB_SELECT_S:
    1796           0 :             MAKE_CURSOR( tblsels_ );
    1797           0 :             break;
    1798             :         case POINTER_TAB_SELECT_E:
    1799           0 :             MAKE_CURSOR( tblsele_ );
    1800           0 :             break;
    1801             :         case POINTER_TAB_SELECT_SE:
    1802           0 :             MAKE_CURSOR( tblselse_ );
    1803           0 :             break;
    1804             :         case POINTER_TAB_SELECT_W:
    1805           0 :             MAKE_CURSOR( tblselw_ );
    1806           0 :             break;
    1807             :         case POINTER_TAB_SELECT_SW:
    1808           0 :             MAKE_CURSOR( tblselsw_ );
    1809           0 :             break;
    1810             : 
    1811             :         // #i20119# Paintbrush tool
    1812             :         case POINTER_PAINTBRUSH :
    1813           0 :             MAKE_CURSOR( paintbrush_ );
    1814           0 :             break;
    1815             : 
    1816             :         default:
    1817             :             OSL_FAIL("pointer not implemented");
    1818           0 :             aCur = XCreateFontCursor( pDisp_, XC_arrow );
    1819           0 :             break;
    1820             :     }
    1821             : 
    1822           0 :     if( None == aCur )
    1823             :     {
    1824             :         XColor      aBlack, aWhite, aDummy;
    1825           0 :         Colormap    hColormap = GetColormap(m_nXDefaultScreen).GetXColormap();
    1826             : 
    1827           0 :         XAllocNamedColor( pDisp_, hColormap, "black", &aBlack, &aDummy );
    1828           0 :         XAllocNamedColor( pDisp_, hColormap, "white", &aWhite, &aDummy );
    1829             : 
    1830             :         aCur = XCreatePixmapCursor( pDisp_,
    1831             :                                     aCursBitmap, aMaskBitmap,
    1832             :                                     &aBlack, &aWhite,
    1833           0 :                                     nXHot, nYHot );
    1834             : 
    1835           0 :         XFreePixmap( pDisp_, aCursBitmap );
    1836           0 :         XFreePixmap( pDisp_, aMaskBitmap );
    1837             :     }
    1838             : 
    1839           0 :     return aCur;
    1840             : }
    1841             : 
    1842           0 : int SalDisplay::CaptureMouse( SalFrame *pCapture )
    1843             : {
    1844           0 :     static const char* pEnv = getenv( "SAL_NO_MOUSEGRABS" );
    1845             : 
    1846           0 :     if( !pCapture )
    1847             :     {
    1848           0 :         m_pCapture = NULL;
    1849           0 :         if( !pEnv || !*pEnv )
    1850           0 :             XUngrabPointer( GetDisplay(), CurrentTime );
    1851           0 :         XFlush( GetDisplay() );
    1852           0 :         return 0;
    1853             :     }
    1854             : 
    1855           0 :     m_pCapture = NULL;
    1856             : 
    1857             :     // FIXME: get rid of X11SalFrame
    1858           0 :     const SystemEnvData* pEnvData = pCapture->GetSystemData();
    1859           0 :     if( !pEnv || !*pEnv )
    1860             :     {
    1861             :         int ret = XGrabPointer( GetDisplay(),
    1862             :                                 (XLIB_Window)pEnvData->aWindow,
    1863             :                                 False,
    1864             :                                 PointerMotionMask| ButtonPressMask|ButtonReleaseMask,
    1865             :                                 GrabModeAsync,
    1866             :                                 GrabModeAsync,
    1867             :                                 None,
    1868             :                                 static_cast<X11SalFrame*>(pCapture)->GetCursor(),
    1869           0 :                                 CurrentTime );
    1870             : 
    1871           0 :         if( ret != GrabSuccess )
    1872             :         {
    1873             :             DBG_ASSERT( 1, "SalDisplay::CaptureMouse could not grab pointer\n");
    1874           0 :             return -1;
    1875             :         }
    1876             :     }
    1877             : 
    1878           0 :     m_pCapture = pCapture;
    1879           0 :     return 1;
    1880             : }
    1881             : 
    1882             : // Events
    1883             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    1884             : 
    1885           0 : sal_Bool SalX11Display::IsEvent()
    1886             : {
    1887           0 :     if( HasUserEvents() || XEventsQueued( pDisp_, QueuedAlready ) )
    1888           0 :         return sal_True;
    1889             : 
    1890           0 :     XFlush( pDisp_ );
    1891           0 :     return sal_False;
    1892             : }
    1893             : 
    1894           0 : void SalX11Display::Yield()
    1895             : {
    1896           0 :     if( DispatchInternalEvent() )
    1897           0 :         return;
    1898             : 
    1899             :     XEvent aEvent;
    1900             :     DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
    1901             :                 osl::Thread::getCurrentIdentifier(),
    1902             :                 "will crash soon since solar mutex not locked in SalDisplay::Yield" );
    1903             : 
    1904           0 :     XNextEvent( pDisp_, &aEvent );
    1905             : 
    1906           0 :     Dispatch( &aEvent );
    1907             : 
    1908             : #ifdef DBG_UTIL
    1909             :     if( GetX11SalData()->HasXErrorOccurred() )
    1910             :     {
    1911             :         XFlush( pDisp_ );
    1912             :         DbgPrintDisplayEvent("SalDisplay::Yield (WasXError)", &aEvent);
    1913             :     }
    1914             : #endif
    1915           0 :     GetX11SalData()->ResetXErrorOccurred();
    1916             : }
    1917             : 
    1918           0 : long SalX11Display::Dispatch( XEvent *pEvent )
    1919             : {
    1920           0 :     if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
    1921             :     {
    1922           0 :         XLIB_Window aWindow = pEvent->xkey.window;
    1923             : 
    1924           0 :         std::list< SalFrame* >::const_iterator it;
    1925           0 :         for( it = m_aFrames.begin(); it != m_aFrames.end(); ++it )
    1926             :         {
    1927           0 :             const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
    1928           0 :             if( pFrame->GetWindow() == aWindow || pFrame->GetShellWindow() == aWindow )
    1929             :             {
    1930           0 :                 aWindow = pFrame->GetWindow();
    1931           0 :                 break;
    1932             :             }
    1933             :         }
    1934           0 :         if( it != m_aFrames.end() )
    1935             :         {
    1936           0 :             if ( mpInputMethod->FilterEvent( pEvent , aWindow ) )
    1937           0 :                 return 0;
    1938           0 :         }
    1939             :     }
    1940             :     else
    1941           0 :         if ( mpInputMethod->FilterEvent( pEvent, None ) )
    1942           0 :             return 0;
    1943             : 
    1944           0 :     SalInstance* pInstance = GetSalData()->m_pInstance;
    1945           0 :     pInstance->CallEventCallback( pEvent, sizeof( XEvent ) );
    1946             : 
    1947           0 :     switch( pEvent->type )
    1948             :     {
    1949             :         case MotionNotify:
    1950           0 :             while( XCheckWindowEvent( pEvent->xany.display,
    1951             :                                       pEvent->xany.window,
    1952             :                                       ButtonMotionMask,
    1953           0 :                                       pEvent ) )
    1954             :                 ;
    1955           0 :             m_nLastUserEventTime = pEvent->xmotion.time;
    1956           0 :             break;
    1957             :         case PropertyNotify:
    1958           0 :             if( pEvent->xproperty.atom == getWMAdaptor()->getAtom( WMAdaptor::VCL_SYSTEM_SETTINGS ) )
    1959             :             {
    1960           0 :                 for( unsigned int i = 0; i < m_aScreens.size(); i++ )
    1961             :                 {
    1962           0 :                     if( pEvent->xproperty.window == m_aScreens[i].m_aRefWindow )
    1963             :                     {
    1964           0 :                         std::list< SalFrame* >::const_iterator it;
    1965           0 :                         for( it = m_aFrames.begin(); it != m_aFrames.end(); ++it )
    1966           0 :                             (*it)->CallCallback( SALEVENT_SETTINGSCHANGED, NULL );
    1967           0 :                         return 0;
    1968             :                     }
    1969             :                 }
    1970             :             }
    1971           0 :             break;
    1972             :         case MappingNotify:
    1973           0 :             if( MappingModifier == pEvent->xmapping.request )
    1974             :             {
    1975           0 :                 XRefreshKeyboardMapping( &pEvent->xmapping );
    1976           0 :                 ModifierMapping();
    1977             :             }
    1978           0 :             break;
    1979             :         case ButtonPress:
    1980             :         case ButtonRelease:
    1981           0 :             m_nLastUserEventTime = pEvent->xbutton.time;
    1982           0 :             break;
    1983             :         case XLIB_KeyPress:
    1984             :         case KeyRelease:
    1985           0 :             m_nLastUserEventTime = pEvent->xkey.time;
    1986           0 :             break;
    1987             :         default:
    1988             : 
    1989           0 :             if (   GetKbdExtension()->UseExtension()
    1990           0 :                 && GetKbdExtension()->GetEventBase() == pEvent->type )
    1991             :             {
    1992           0 :                 GetKbdExtension()->Dispatch( pEvent );
    1993           0 :                 return 1;
    1994             :             }
    1995           0 :             break;
    1996             :     }
    1997             : 
    1998           0 :     std::list< SalFrame* >::iterator it;
    1999           0 :     for( it = m_aFrames.begin(); it != m_aFrames.end(); ++it )
    2000             :     {
    2001           0 :         X11SalFrame* pFrame = static_cast< X11SalFrame* >(*it);
    2002           0 :         XLIB_Window aDispatchWindow = pEvent->xany.window;
    2003           0 :         if( pFrame->GetWindow() == aDispatchWindow
    2004           0 :             || pFrame->GetShellWindow() == aDispatchWindow
    2005           0 :             || pFrame->GetForeignParent() == aDispatchWindow
    2006             :             )
    2007             :         {
    2008           0 :             return pFrame->Dispatch( pEvent );
    2009             :         }
    2010           0 :         if( pEvent->type == ConfigureNotify && pEvent->xconfigure.window == pFrame->GetStackingWindow() )
    2011             :         {
    2012           0 :             return pFrame->Dispatch( pEvent );
    2013             :         }
    2014             :     }
    2015             : 
    2016             :     // dispatch to salobjects
    2017           0 :     X11SalObject::Dispatch( pEvent );
    2018             : 
    2019             :     // is this perhaps a root window that changed size ?
    2020           0 :     processRandREvent( pEvent );
    2021             : 
    2022           0 :     return 0;
    2023             : }
    2024             : 
    2025             : #ifdef DBG_UTIL
    2026             : void SalDisplay::DbgPrintDisplayEvent(const char *pComment, XEvent *pEvent) const
    2027             : {
    2028             :     if( pEvent->type <= MappingNotify )
    2029             :     {
    2030             :         fprintf( stderr, "[%s] %s s=%d w=%ld\n",
    2031             :                  pComment,
    2032             :                  EventNames[pEvent->type],
    2033             :                  pEvent->xany.send_event,
    2034             :                  pEvent->xany.window );
    2035             : 
    2036             :         switch( pEvent->type )
    2037             :         {
    2038             :             case XLIB_KeyPress:
    2039             :             case KeyRelease:
    2040             :                 fprintf( stderr, "\t\ts=%d c=%d\n",
    2041             :                          pEvent->xkey.state,
    2042             :                          pEvent->xkey.keycode );
    2043             :                 break;
    2044             : 
    2045             :             case ButtonPress:
    2046             :             case ButtonRelease:
    2047             :                 fprintf( stderr, "\t\ts=%d b=%d x=%d y=%d rx=%d ry=%d\n",
    2048             :                          pEvent->xbutton.state,
    2049             :                          pEvent->xbutton.button,
    2050             :                          pEvent->xbutton.x,
    2051             :                          pEvent->xbutton.y,
    2052             :                          pEvent->xbutton.x_root,
    2053             :                          pEvent->xbutton.y_root );
    2054             :                 break;
    2055             : 
    2056             :             case MotionNotify:
    2057             :                 fprintf( stderr, "\t\ts=%d x=%d y=%d\n",
    2058             :                          pEvent->xmotion.state,
    2059             :                          pEvent->xmotion.x,
    2060             :                          pEvent->xmotion.y );
    2061             :                 break;
    2062             : 
    2063             :             case EnterNotify:
    2064             :             case LeaveNotify:
    2065             :                 fprintf( stderr, "\t\tm=%d f=%d x=%d y=%d\n",
    2066             :                          pEvent->xcrossing.mode,
    2067             :                          pEvent->xcrossing.focus,
    2068             :                          pEvent->xcrossing.x,
    2069             :                          pEvent->xcrossing.y );
    2070             :                 break;
    2071             : 
    2072             :             case FocusIn:
    2073             :             case FocusOut:
    2074             :                 fprintf( stderr, "\t\tm=%d d=%d\n",
    2075             :                          pEvent->xfocus.mode,
    2076             :                          pEvent->xfocus.detail );
    2077             :                 break;
    2078             : 
    2079             :             case Expose:
    2080             :             case GraphicsExpose:
    2081             :                 fprintf( stderr, "\t\tc=%d %d*%d %d+%d\n",
    2082             :                          pEvent->xexpose.count,
    2083             :                          pEvent->xexpose.width,
    2084             :                          pEvent->xexpose.height,
    2085             :                          pEvent->xexpose.x,
    2086             :                          pEvent->xexpose.y );
    2087             :                 break;
    2088             : 
    2089             :             case VisibilityNotify:
    2090             :                 fprintf( stderr, "\t\ts=%d\n",
    2091             :                          pEvent->xvisibility.state );
    2092             :                 break;
    2093             : 
    2094             :             case CreateNotify:
    2095             :             case DestroyNotify:
    2096             :                 break;
    2097             : 
    2098             :             case MapNotify:
    2099             :             case UnmapNotify:
    2100             :                 break;
    2101             : 
    2102             :             case ReparentNotify:
    2103             :                 fprintf( stderr, "\t\tp=%d x=%d y=%d\n",
    2104             :                          sal::static_int_cast< int >(pEvent->xreparent.parent),
    2105             :                          pEvent->xreparent.x,
    2106             :                          pEvent->xreparent.y );
    2107             :                 break;
    2108             : 
    2109             :             case ConfigureNotify:
    2110             :                 fprintf( stderr, "\t\tb=%d %d*%d %d+%d\n",
    2111             :                          pEvent->xconfigure.border_width,
    2112             :                          pEvent->xconfigure.width,
    2113             :                          pEvent->xconfigure.height,
    2114             :                          pEvent->xconfigure.x,
    2115             :                          pEvent->xconfigure.y );
    2116             :                 break;
    2117             : 
    2118             :             case PropertyNotify:
    2119             :                 fprintf( stderr, "\t\ta=%s (0x%X)\n",
    2120             :                          GetAtomName( pDisp_, pEvent->xproperty.atom ),
    2121             :                          sal::static_int_cast< unsigned int >(
    2122             :                              pEvent->xproperty.atom) );
    2123             :                 break;
    2124             : 
    2125             :             case ColormapNotify:
    2126             :                 fprintf( stderr, "\t\tc=%ld n=%d s=%d\n",
    2127             :                          pEvent->xcolormap.colormap,
    2128             :                          pEvent->xcolormap.c_new,
    2129             :                          pEvent->xcolormap.state );
    2130             :                 break;
    2131             : 
    2132             :             case ClientMessage:
    2133             :                 fprintf( stderr, "\t\ta=%s (0x%X) f=%i [0x%lX,0x%lX,0x%lX,0x%lX,0x%lX])\n",
    2134             :                          GetAtomName( pDisp_, pEvent->xclient.message_type ),
    2135             :                          sal::static_int_cast< unsigned int >(
    2136             :                              pEvent->xclient.message_type),
    2137             :                          pEvent->xclient.format,
    2138             :                          pEvent->xclient.data.l[0],
    2139             :                          pEvent->xclient.data.l[1],
    2140             :                          pEvent->xclient.data.l[2],
    2141             :                          pEvent->xclient.data.l[3],
    2142             :                          pEvent->xclient.data.l[4] );
    2143             :                 break;
    2144             : 
    2145             :             case MappingNotify:
    2146             :                 fprintf( stderr, "\t\tr=%sd\n",
    2147             :                          MappingModifier == pEvent->xmapping.request
    2148             :                          ? "MappingModifier"
    2149             :                          : MappingKeyboard == pEvent->xmapping.request
    2150             :                            ? "MappingKeyboard"
    2151             :                            : "MappingPointer" );
    2152             : 
    2153             :                 break;
    2154             :         }
    2155             :     }
    2156             :     else
    2157             :         fprintf( stderr, "[%s] %d s=%d w=%ld\n",
    2158             :                  pComment,
    2159             :                  pEvent->type,
    2160             :                  pEvent->xany.send_event,
    2161             :                  pEvent->xany.window );
    2162             : }
    2163             : #endif
    2164             : 
    2165             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2166           0 : void SalDisplay::PrintInfo() const
    2167             : {
    2168           0 :     if( IsDisplay() )
    2169             :     {
    2170           0 :         fprintf( stderr, "\n" );
    2171           0 :         fprintf( stderr, "Environment\n" );
    2172             :         fprintf( stderr, "\t$DISPLAY          \t\"%s\"\n",
    2173           0 :                  GetEnv( "DISPLAY" ) );
    2174             :         fprintf( stderr, "\t$SAL_VISUAL       \t\"%s\"\n",
    2175           0 :                  GetEnv( "SAL_VISUAL" ) );
    2176             :         fprintf( stderr, "\t$SAL_IGNOREXERRORS\t\"%s\"\n",
    2177           0 :                  GetEnv( "SAL_IGNOREXERRORS" ) );
    2178             :         fprintf( stderr, "\t$SAL_PROPERTIES   \t\"%s\"\n",
    2179           0 :                  GetEnv( "SAL_PROPERTIES" ) );
    2180             :         fprintf( stderr, "\t$SAL_SYNCHRONIZE  \t\"%s\"\n",
    2181           0 :                  GetEnv( "SAL_SYNCHRONIZE" ) );
    2182             : 
    2183             :         char sHostname[ 120 ];
    2184           0 :         gethostname (sHostname, 120 );
    2185           0 :         fprintf( stderr, "Client\n" );
    2186             :         fprintf( stderr, "\tHost              \t\"%s\"\n",
    2187           0 :                  sHostname );
    2188             : 
    2189           0 :         fprintf( stderr, "Display\n" );
    2190             :         fprintf( stderr, "\tHost              \t\"%s\"\n",
    2191           0 :                  DisplayString(pDisp_) );
    2192             :         fprintf( stderr, "\tVendor (Release)  \t\"%s (%d)\"\n",
    2193           0 :                  ServerVendor(pDisp_), VendorRelease(pDisp_) );
    2194             :         fprintf( stderr, "\tProtocol          \t%d.%d\n",
    2195           0 :                  ProtocolVersion(pDisp_), ProtocolRevision(pDisp_) );
    2196             :         fprintf( stderr, "\tScreen (count,def)\t%d (%d,%d)\n",
    2197             :                  m_nXDefaultScreen.getXScreen(),
    2198           0 :                  ScreenCount(pDisp_), DefaultScreen(pDisp_) );
    2199             :         fprintf( stderr, "\tshift ctrl alt    \t%s (0x%X) %s (0x%X) %s (0x%X)\n",
    2200             :                  KeyStr( nShiftKeySym_ ), sal::static_int_cast< unsigned int >(nShiftKeySym_),
    2201             :                  KeyStr( nCtrlKeySym_ ),  sal::static_int_cast< unsigned int >(nCtrlKeySym_),
    2202           0 :                  KeyStr( nMod1KeySym_ ),  sal::static_int_cast< unsigned int >(nMod1KeySym_) );
    2203           0 :         if( XExtendedMaxRequestSize(pDisp_) * 4 )
    2204             :             fprintf( stderr, "\tXMaxRequestSize   \t%ld %ld [bytes]\n",
    2205           0 :                      XMaxRequestSize(pDisp_) * 4, XExtendedMaxRequestSize(pDisp_) * 4 );
    2206           0 :         if( GetProperties() != PROPERTY_DEFAULT )
    2207           0 :             fprintf( stderr, "\tProperties        \t0x%lX\n", GetProperties() );
    2208           0 :         fprintf( stderr, "\tWMName            \t%s\n", rtl::OUStringToOString( getWMAdaptor()->getWindowManagerName(), osl_getThreadTextEncoding() ).getStr() );
    2209             :     }
    2210           0 :     fprintf( stderr, "Screen\n" );
    2211             :     fprintf( stderr, "\tResolution/Size   \t%ld*%ld %ld*%ld %.1lf\"\n",
    2212             :              aResolution_.A(), aResolution_.B(),
    2213           0 :              m_aScreens[m_nXDefaultScreen.getXScreen()].m_aSize.Width(),
    2214           0 :              m_aScreens[m_nXDefaultScreen.getXScreen()].m_aSize.Height(),
    2215           0 :              Hypothenuse( DisplayWidthMM ( pDisp_, m_nXDefaultScreen.getXScreen() ),
    2216           0 :                           DisplayHeightMM( pDisp_, m_nXDefaultScreen.getXScreen() ) ) / 25.4 );
    2217             :     fprintf( stderr, "\tBlack&White       \t%lu %lu\n",
    2218           0 :              GetColormap(m_nXDefaultScreen).GetBlackPixel(),
    2219           0 :              GetColormap(m_nXDefaultScreen).GetWhitePixel() );
    2220             :     fprintf( stderr, "\tRGB               \t0x%lx 0x%lx 0x%lx\n",
    2221           0 :              GetVisual(m_nXDefaultScreen).red_mask,
    2222           0 :              GetVisual(m_nXDefaultScreen).green_mask,
    2223           0 :              GetVisual(m_nXDefaultScreen).blue_mask );
    2224           0 : }
    2225             : 
    2226           0 : void SalDisplay::addXineramaScreenUnique( int i, long i_nX, long i_nY, long i_nWidth, long i_nHeight )
    2227             : {
    2228             :     // see if any frame buffers are at the same coordinates
    2229             :     // this can happen with weird configuration e.g. on
    2230             :     // XFree86 and Clone displays
    2231           0 :     const size_t nScreens = m_aXineramaScreens.size();
    2232           0 :     for( size_t n = 0; n < nScreens; n++ )
    2233             :     {
    2234           0 :         if( m_aXineramaScreens[n].Left() == i_nX &&
    2235           0 :             m_aXineramaScreens[n].Top() == i_nY )
    2236             :         {
    2237           0 :             if( m_aXineramaScreens[n].GetWidth() < i_nWidth ||
    2238           0 :                 m_aXineramaScreens[n].GetHeight() < i_nHeight )
    2239             :             {
    2240           0 :                 m_aXineramaScreenIndexMap[i] = n;
    2241           0 :                 m_aXineramaScreens[n].SetSize( Size( i_nWidth, i_nHeight ) );
    2242             :             }
    2243           0 :             return;
    2244             :         }
    2245             :     }
    2246           0 :     m_aXineramaScreenIndexMap[i] = m_aXineramaScreens.size();
    2247           0 :     m_aXineramaScreens.push_back( Rectangle( Point( i_nX, i_nY ), Size( i_nWidth, i_nHeight ) ) );
    2248             : }
    2249             : 
    2250           0 : void SalDisplay::InitXinerama()
    2251             : {
    2252           0 :     if( m_aScreens.size() > 1 )
    2253             :     {
    2254           0 :         m_bXinerama = false;
    2255           0 :         return; // multiple screens mean no xinerama
    2256             :     }
    2257             : #if defined(USE_XINERAMA_XSUN)
    2258             :     int nFramebuffers = 1;
    2259             :     if( XineramaGetState( pDisp_, m_nDefaultScreen ) )
    2260             :     {
    2261             :         XRectangle pFramebuffers[MAXFRAMEBUFFERS];
    2262             :         unsigned char hints[MAXFRAMEBUFFERS];
    2263             :         int result = XineramaGetInfo( pDisp_,
    2264             :                                       m_nDefaultScreen,
    2265             :                                       pFramebuffers,
    2266             :                                       hints,
    2267             :                                       &nFramebuffers );
    2268             :         if( result > 0 && nFramebuffers > 1 )
    2269             :         {
    2270             :             m_bXinerama = true;
    2271             :             m_aXineramaScreens = std::vector<Rectangle>();
    2272             :             m_aXineramaScreenIndexMap = std::vector<int>(nFramebuffers);
    2273             :             for( int i = 0; i < nFramebuffers; i++ )
    2274             :                 addXineramaScreenUnique( i, pFramebuffers[i].x,
    2275             :                                          pFramebuffers[i].y,
    2276             :                                          pFramebuffers[i].width,
    2277             :                                          pFramebuffers[i].height );
    2278             :         }
    2279             :     }
    2280             : #elif defined(USE_XINERAMA_XORG)
    2281           0 :     if( XineramaIsActive( pDisp_ ) )
    2282             :     {
    2283           0 :         int nFramebuffers = 1;
    2284           0 :         XineramaScreenInfo* pScreens = XineramaQueryScreens( pDisp_, &nFramebuffers );
    2285           0 :         if( pScreens )
    2286             :         {
    2287           0 :             if( nFramebuffers > 1 )
    2288             :             {
    2289           0 :                 m_aXineramaScreens = std::vector<Rectangle>();
    2290           0 :                 m_aXineramaScreenIndexMap = std::vector<int>(nFramebuffers);
    2291           0 :                 for( int i = 0; i < nFramebuffers; i++ )
    2292             :                 {
    2293           0 :                     addXineramaScreenUnique( i, pScreens[i].x_org,
    2294           0 :                                              pScreens[i].y_org,
    2295           0 :                                              pScreens[i].width,
    2296           0 :                                              pScreens[i].height );
    2297             :                 }
    2298           0 :                 m_bXinerama = m_aXineramaScreens.size() > 1;
    2299             :             }
    2300           0 :             XFree( pScreens );
    2301             :         }
    2302             :     }
    2303             : #endif
    2304             : #if OSL_DEBUG_LEVEL > 1
    2305             :     if( m_bXinerama )
    2306             :     {
    2307             :         for( std::vector< Rectangle >::const_iterator it = m_aXineramaScreens.begin(); it != m_aXineramaScreens.end(); ++it )
    2308             :             fprintf( stderr, "Xinerama screen: %ldx%ld+%ld+%ld\n", it->GetWidth(), it->GetHeight(), it->Left(), it->Top() );
    2309             :     }
    2310             : #endif
    2311             : }
    2312             : 
    2313             : 
    2314             : extern "C"
    2315             : {
    2316           0 :     static Bool timestamp_predicate( Display*, XEvent* i_pEvent, XPointer i_pArg )
    2317             :     {
    2318           0 :         SalDisplay* pSalDisplay = reinterpret_cast<SalDisplay*>(i_pArg);
    2319           0 :         if( i_pEvent->type == PropertyNotify &&
    2320           0 :             i_pEvent->xproperty.window == pSalDisplay->GetDrawable( pSalDisplay->GetDefaultXScreen() ) &&
    2321           0 :             i_pEvent->xproperty.atom == pSalDisplay->getWMAdaptor()->getAtom( WMAdaptor::SAL_GETTIMEEVENT )
    2322             :             )
    2323           0 :         return True;
    2324             : 
    2325           0 :         return False;
    2326             :     }
    2327             : }
    2328             : 
    2329           0 : XLIB_Time SalDisplay::GetLastUserEventTime( bool i_bAlwaysReget ) const
    2330             : {
    2331           0 :     if( m_nLastUserEventTime == CurrentTime || i_bAlwaysReget )
    2332             :     {
    2333             :         // get current server time
    2334           0 :         unsigned char c = 0;
    2335             :         XEvent aEvent;
    2336           0 :         Atom nAtom = getWMAdaptor()->getAtom( WMAdaptor::SAL_GETTIMEEVENT );
    2337             :         XChangeProperty( GetDisplay(), GetDrawable( GetDefaultXScreen() ),
    2338           0 :                          nAtom, nAtom, 8, PropModeReplace, &c, 1 );
    2339           0 :         XFlush( GetDisplay() );
    2340             : 
    2341           0 :         if( ! XIfEventWithTimeout( &aEvent, (XPointer)this, timestamp_predicate ) )
    2342             :         {
    2343             :             // this should not happen at all; still sometimes it happens
    2344           0 :             aEvent.xproperty.time = CurrentTime;
    2345             :         }
    2346             : 
    2347           0 :         m_nLastUserEventTime = aEvent.xproperty.time;
    2348             :     }
    2349           0 :     return m_nLastUserEventTime;
    2350             : }
    2351             : 
    2352           0 : bool SalDisplay::XIfEventWithTimeout( XEvent* o_pEvent, XPointer i_pPredicateData,
    2353             :                                       X_if_predicate i_pPredicate, long i_nTimeout ) const
    2354             : {
    2355             :     /* #i99360# ugly workaround an X11 library bug
    2356             :        this replaces the following call:
    2357             :        XIfEvent( GetDisplay(), o_pEvent, i_pPredicate, i_pPredicateData );
    2358             :     */
    2359           0 :     bool bRet = true;
    2360             : 
    2361           0 :     if( ! XCheckIfEvent( GetDisplay(), o_pEvent, i_pPredicate, i_pPredicateData ) )
    2362             :     {
    2363             :         // wait for some event to arrive
    2364             :         struct pollfd aFD;
    2365           0 :         aFD.fd = ConnectionNumber(GetDisplay());
    2366           0 :         aFD.events = POLLIN;
    2367           0 :         aFD.revents = 0;
    2368           0 :         poll( &aFD, 1, i_nTimeout );
    2369           0 :         if( ! XCheckIfEvent( GetDisplay(), o_pEvent, i_pPredicate, i_pPredicateData ) )
    2370             :         {
    2371           0 :             poll( &aFD, 1, i_nTimeout ); // try once more for a packet of events from the Xserver
    2372           0 :             if( ! XCheckIfEvent( GetDisplay(), o_pEvent, i_pPredicate, i_pPredicateData ) )
    2373             :             {
    2374           0 :                 bRet = false;
    2375             :             }
    2376             :         }
    2377             :     }
    2378           0 :     return bRet;
    2379             : }
    2380             : 
    2381             : // -=-= SalVisual -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2382             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2383           0 : SalVisual::SalVisual()
    2384             : {
    2385           0 :     memset( this, 0, sizeof( SalVisual ) );
    2386           0 : }
    2387             : 
    2388           0 : SalVisual::SalVisual( const XVisualInfo* pXVI )
    2389             : {
    2390           0 :     *(XVisualInfo*)this = *pXVI;
    2391           0 :     if( GetClass() == TrueColor )
    2392             :     {
    2393           0 :         nRedShift_      = sal_Shift( red_mask );
    2394           0 :         nGreenShift_    = sal_Shift( green_mask );
    2395           0 :         nBlueShift_     = sal_Shift( blue_mask );
    2396             : 
    2397           0 :         nRedBits_       = sal_significantBits( red_mask );
    2398           0 :         nGreenBits_     = sal_significantBits( green_mask );
    2399           0 :         nBlueBits_      = sal_significantBits( blue_mask );
    2400             : 
    2401           0 :         if( GetDepth() == 24 )
    2402           0 :             if( red_mask == 0xFF0000 )
    2403           0 :                 if( green_mask == 0xFF00 )
    2404           0 :                     if( blue_mask  == 0xFF )
    2405           0 :                         eRGBMode_ = RGB;
    2406             :                     else
    2407           0 :                         eRGBMode_ = otherSalRGB;
    2408           0 :                 else if( blue_mask  == 0xFF00 )
    2409           0 :                     if( green_mask == 0xFF )
    2410           0 :                         eRGBMode_ = RBG;
    2411             :                     else
    2412           0 :                         eRGBMode_ = otherSalRGB;
    2413             :                 else
    2414           0 :                     eRGBMode_ = otherSalRGB;
    2415           0 :             else if( green_mask == 0xFF0000 )
    2416           0 :                 if( red_mask == 0xFF00 )
    2417           0 :                     if( blue_mask  == 0xFF )
    2418           0 :                         eRGBMode_ = GRB;
    2419             :                     else
    2420           0 :                         eRGBMode_ = otherSalRGB;
    2421           0 :                 else if( blue_mask == 0xFF00 )
    2422           0 :                     if( red_mask  == 0xFF )
    2423           0 :                         eRGBMode_ = GBR;
    2424             :                     else
    2425           0 :                         eRGBMode_ = otherSalRGB;
    2426             :                 else
    2427           0 :                     eRGBMode_ = otherSalRGB;
    2428           0 :             else if( blue_mask == 0xFF0000 )
    2429           0 :                 if( red_mask == 0xFF00 )
    2430           0 :                     if( green_mask  == 0xFF )
    2431           0 :                         eRGBMode_ = BRG;
    2432             :                     else
    2433           0 :                         eRGBMode_ = otherSalRGB;
    2434           0 :                 else if( green_mask == 0xFF00 )
    2435           0 :                     if( red_mask == 0xFF )
    2436           0 :                         eRGBMode_ = BGR;
    2437             :                     else
    2438           0 :                         eRGBMode_ = otherSalRGB;
    2439             :                 else
    2440           0 :                     eRGBMode_ = otherSalRGB;
    2441             :             else
    2442           0 :                 eRGBMode_ = otherSalRGB;
    2443             :         else
    2444           0 :             eRGBMode_ = otherSalRGB;
    2445             :     }
    2446           0 : }
    2447             : 
    2448             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2449           0 : SalVisual::~SalVisual()
    2450             : {
    2451           0 :     if( -1 == screen && VisualID(-1) == visualid ) delete visual;
    2452           0 : }
    2453             : 
    2454             : // Konvertiert die Reihenfolge der Bytes eines Pixel in Bytes eines SalColors
    2455             : // fuer die 6 XXXA ist das nicht reversibel
    2456             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2457             : // SalColor is RGB (ABGR) a=0xFF000000, r=0xFF0000, g=0xFF00, b=0xFF
    2458             : 
    2459             : #define SALCOLOR        RGB
    2460             : #define SALCOLORREVERSE BGR
    2461             : 
    2462             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2463           0 : SalColor SalVisual::GetTCColor( Pixel nPixel ) const
    2464             : {
    2465           0 :     if( SALCOLOR == eRGBMode_ )
    2466           0 :         return (SalColor)nPixel;
    2467             : 
    2468           0 :     if( SALCOLORREVERSE == eRGBMode_ )
    2469           0 :         return MAKE_SALCOLOR( (nPixel & 0x0000FF),
    2470             :                               (nPixel & 0x00FF00) >>  8,
    2471             :                               (nPixel & 0xFF0000) >> 16);
    2472             : 
    2473           0 :     Pixel r = nPixel & red_mask;
    2474           0 :     Pixel g = nPixel & green_mask;
    2475           0 :     Pixel b = nPixel & blue_mask;
    2476             : 
    2477           0 :     if( otherSalRGB != eRGBMode_ ) // 8+8+8=24
    2478           0 :         return MAKE_SALCOLOR( r >> nRedShift_,
    2479             :                               g >> nGreenShift_,
    2480             :                               b >> nBlueShift_ );
    2481             : 
    2482           0 :     if( nRedShift_ > 0 )   r >>= nRedShift_;   else r <<= -nRedShift_;
    2483           0 :     if( nGreenShift_ > 0 ) g >>= nGreenShift_; else g <<= -nGreenShift_;
    2484           0 :     if( nBlueShift_ > 0 )  b >>= nBlueShift_;  else b <<= -nBlueShift_;
    2485             : 
    2486           0 :     if( nRedBits_ != 8 )
    2487           0 :         r |= (r & 0xff) >> (8-nRedBits_);
    2488           0 :     if( nGreenBits_ != 8 )
    2489           0 :         g |= (g & 0xff) >> (8-nGreenBits_);
    2490           0 :     if( nBlueBits_ != 8 )
    2491           0 :         b |= (b & 0xff) >> (8-nBlueBits_);
    2492             : 
    2493           0 :     return MAKE_SALCOLOR( r, g, b );
    2494             : }
    2495             : 
    2496           0 : Pixel SalVisual::GetTCPixel( SalColor nSalColor ) const
    2497             : {
    2498           0 :     if( SALCOLOR == eRGBMode_ )
    2499           0 :         return (Pixel)nSalColor;
    2500             : 
    2501           0 :     Pixel r = (Pixel)SALCOLOR_RED( nSalColor );
    2502           0 :     Pixel g = (Pixel)SALCOLOR_GREEN( nSalColor );
    2503           0 :     Pixel b = (Pixel)SALCOLOR_BLUE( nSalColor );
    2504             : 
    2505           0 :     if( SALCOLORREVERSE == eRGBMode_ )
    2506           0 :         return (b << 16) | (g << 8) | (r);
    2507             : 
    2508           0 :     if( otherSalRGB != eRGBMode_ ) // 8+8+8=24
    2509           0 :         return (r << nRedShift_) | (g << nGreenShift_) | (b << nBlueShift_);
    2510             : 
    2511           0 :     if( nRedShift_ > 0 )   r <<= nRedShift_;   else r >>= -nRedShift_;
    2512           0 :     if( nGreenShift_ > 0 ) g <<= nGreenShift_; else g >>= -nGreenShift_;
    2513           0 :     if( nBlueShift_ > 0 )  b <<= nBlueShift_;  else b >>= -nBlueShift_;
    2514             : 
    2515           0 :     return (r&red_mask) | (g&green_mask) | (b&blue_mask);
    2516             : }
    2517             : 
    2518             : // -=-= SalColormap -=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2519             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2520           0 : SalColormap::SalColormap( const SalDisplay *pDisplay, Colormap hColormap,
    2521             :                           SalX11Screen nXScreen )
    2522             :     : m_pDisplay( pDisplay ),
    2523             :       m_hColormap( hColormap ),
    2524           0 :       m_nXScreen( nXScreen )
    2525             : {
    2526           0 :     m_aVisual = m_pDisplay->GetVisual( m_nXScreen );
    2527             : 
    2528             :     XColor aColor;
    2529             : 
    2530           0 :     GetXPixel( aColor, 0x00, 0x00, 0x00 );
    2531           0 :     m_nBlackPixel = aColor.pixel;
    2532             : 
    2533           0 :     GetXPixel( aColor, 0xFF, 0xFF, 0xFF );
    2534           0 :     m_nWhitePixel = aColor.pixel;
    2535             : 
    2536           0 :     m_nUsed = 1 << m_aVisual.GetDepth();
    2537             : 
    2538           0 :     if( m_aVisual.GetClass() == PseudoColor )
    2539             :     {
    2540             :         int r, g, b;
    2541             : 
    2542             :         // black, white, gray, ~gray = 4
    2543           0 :         GetXPixels( aColor, 0xC0, 0xC0, 0xC0 );
    2544             : 
    2545             :         // light colors: 3 * 2 = 6
    2546             : 
    2547           0 :         GetXPixels( aColor, 0x00, 0x00, 0xFF );
    2548           0 :         GetXPixels( aColor, 0x00, 0xFF, 0x00 );
    2549           0 :         GetXPixels( aColor, 0x00, 0xFF, 0xFF );
    2550             : 
    2551             :         // standard colors: 7 * 2 = 14
    2552           0 :         GetXPixels( aColor, 0x00, 0x00, 0x80 );
    2553           0 :         GetXPixels( aColor, 0x00, 0x80, 0x00 );
    2554           0 :         GetXPixels( aColor, 0x00, 0x80, 0x80 );
    2555           0 :         GetXPixels( aColor, 0x80, 0x00, 0x00 );
    2556           0 :         GetXPixels( aColor, 0x80, 0x00, 0x80 );
    2557           0 :         GetXPixels( aColor, 0x80, 0x80, 0x00 );
    2558           0 :         GetXPixels( aColor, 0x80, 0x80, 0x80 );
    2559           0 :         GetXPixels( aColor, 0x00, 0xB8, 0xFF ); // Blue 7
    2560             : 
    2561             :         // cube: 6*6*6 - 8 = 208
    2562           0 :         for( r = 0; r < 0x100; r += 0x33 ) // 0x33, 0x66, 0x99, 0xCC, 0xFF
    2563           0 :             for( g = 0; g < 0x100; g += 0x33 )
    2564           0 :                 for( b = 0; b < 0x100; b += 0x33 )
    2565           0 :                     GetXPixels( aColor, r, g, b );
    2566             : 
    2567             :         // gray: 16 - 6 = 10
    2568           0 :         for( g = 0x11; g < 0xFF; g += 0x11 )
    2569           0 :             GetXPixels( aColor, g, g, g );
    2570             : 
    2571             :         // green: 16 - 6 = 10
    2572           0 :         for( g = 0x11; g < 0xFF; g += 0x11 )
    2573           0 :             GetXPixels( aColor, 0, g, 0 );
    2574             : 
    2575             :         // red: 16 - 6 = 10
    2576           0 :         for( r = 0x11; r < 0xFF; r += 0x11 )
    2577           0 :             GetXPixels( aColor, r, 0, 0 );
    2578             : 
    2579             :         // blue: 16 - 6 = 10
    2580           0 :         for( b = 0x11; b < 0xFF; b += 0x11 )
    2581           0 :             GetXPixels( aColor, 0, 0, b );
    2582             :     }
    2583           0 : }
    2584             : 
    2585             : // MonoChrome
    2586           0 : SalColormap::SalColormap()
    2587           0 :     : m_pDisplay( GetGenericData()->GetSalDisplay() ),
    2588             :       m_hColormap( None ),
    2589             :       m_nWhitePixel( 1 ),
    2590             :       m_nBlackPixel( 0 ),
    2591             :       m_nUsed( 2 ),
    2592           0 :       m_nXScreen( m_pDisplay != NULL ? m_pDisplay->GetDefaultXScreen() : SalX11Screen( 0 ) )
    2593             : {
    2594           0 :     m_aPalette = std::vector<SalColor>(m_nUsed);
    2595             : 
    2596           0 :     m_aPalette[m_nBlackPixel] = SALCOLOR_BLACK;
    2597           0 :     m_aPalette[m_nWhitePixel] = SALCOLOR_WHITE;
    2598           0 : }
    2599             : 
    2600             : // TrueColor
    2601           0 : SalColormap::SalColormap( sal_uInt16 nDepth )
    2602           0 :     : m_pDisplay( GetGenericData()->GetSalDisplay() ),
    2603             :       m_hColormap( None ),
    2604             :       m_nWhitePixel( (1 << nDepth) - 1 ),
    2605             :       m_nBlackPixel( 0x00000000 ),
    2606             :       m_nUsed( 1 << nDepth ),
    2607           0 :       m_nXScreen( GetGenericData()->GetSalDisplay()->GetDefaultXScreen() )
    2608             : {
    2609           0 :     const SalVisual *pVisual = &m_pDisplay->GetVisual( m_nXScreen );
    2610             : 
    2611           0 :     if( pVisual->GetClass() == TrueColor && pVisual->GetDepth() == nDepth )
    2612           0 :         m_aVisual = *pVisual;
    2613             :     else
    2614             :     {
    2615             :         XVisualInfo aVI;
    2616             : 
    2617           0 :         if( !XMatchVisualInfo( m_pDisplay->GetDisplay(),
    2618           0 :                                m_pDisplay->GetDefaultXScreen().getXScreen(),
    2619             :                                nDepth,
    2620             :                                TrueColor,
    2621           0 :                                &aVI ) )
    2622             :         {
    2623           0 :             aVI.visual          = new Visual();
    2624           0 :             aVI.visualid        = (VisualID)0; // beware of temporary destructor below
    2625           0 :             aVI.screen          = 0;
    2626           0 :             aVI.depth           = nDepth;
    2627           0 :             aVI.c_class         = TrueColor;
    2628           0 :             if( 24 == nDepth ) // 888
    2629             :             {
    2630           0 :                 aVI.red_mask        = 0xFF0000;
    2631           0 :                 aVI.green_mask      = 0x00FF00;
    2632           0 :                 aVI.blue_mask       = 0x0000FF;
    2633             :             }
    2634           0 :             else if( 16 == nDepth ) // 565
    2635             :             {
    2636           0 :                 aVI.red_mask        = 0x00F800;
    2637           0 :                 aVI.green_mask      = 0x0007E0;
    2638           0 :                 aVI.blue_mask       = 0x00001F;
    2639             :             }
    2640           0 :             else if( 15 == nDepth ) // 555
    2641             :             {
    2642           0 :                 aVI.red_mask        = 0x007C00;
    2643           0 :                 aVI.green_mask      = 0x0003E0;
    2644           0 :                 aVI.blue_mask       = 0x00001F;
    2645             :             }
    2646           0 :             else if( 12 == nDepth ) // 444
    2647             :             {
    2648           0 :                 aVI.red_mask        = 0x000F00;
    2649           0 :                 aVI.green_mask      = 0x0000F0;
    2650           0 :                 aVI.blue_mask       = 0x00000F;
    2651             :             }
    2652           0 :             else if( 8 == nDepth ) // 332
    2653             :             {
    2654           0 :                 aVI.red_mask        = 0x0000E0;
    2655           0 :                 aVI.green_mask      = 0x00001C;
    2656           0 :                 aVI.blue_mask       = 0x000003;
    2657             :             }
    2658             :             else
    2659             :             {
    2660           0 :                 aVI.red_mask        = 0x000000;
    2661           0 :                 aVI.green_mask      = 0x000000;
    2662           0 :                 aVI.blue_mask       = 0x000000;
    2663             :             }
    2664           0 :             aVI.colormap_size   = 0;
    2665           0 :             aVI.bits_per_rgb    = 8;
    2666             : 
    2667           0 :             aVI.visual->ext_data        = NULL;
    2668           0 :             aVI.visual->visualid        = aVI.visualid;
    2669           0 :             aVI.visual->c_class         = aVI.c_class;
    2670           0 :             aVI.visual->red_mask        = aVI.red_mask;
    2671           0 :             aVI.visual->green_mask      = aVI.green_mask;
    2672           0 :             aVI.visual->blue_mask       = aVI.blue_mask;
    2673           0 :             aVI.visual->bits_per_rgb    = aVI.bits_per_rgb;
    2674           0 :             aVI.visual->map_entries     = aVI.colormap_size;
    2675             : 
    2676           0 :             m_aVisual = SalVisual( &aVI );
    2677             :             // give ownership of constructed Visual() to m_aVisual
    2678             :             // see SalVisual destructor
    2679           0 :             m_aVisual.visualid        = (VisualID)-1;
    2680           0 :             m_aVisual.screen          = -1;
    2681             :         }
    2682             :         else
    2683           0 :             m_aVisual = SalVisual( &aVI );
    2684             :     }
    2685           0 : }
    2686             : 
    2687           0 : SalColormap::~SalColormap()
    2688             : {
    2689             : #ifdef DBG_UTIL
    2690             :     m_hColormap      = None;
    2691             :     m_pDisplay       = NULL;
    2692             : #endif
    2693           0 : }
    2694             : 
    2695           0 : void SalColormap::GetPalette()
    2696             : {
    2697             :     Pixel i;
    2698           0 :     m_aPalette = std::vector<SalColor>(m_nUsed);
    2699             : 
    2700           0 :     XColor *aColor = new XColor[m_nUsed];
    2701             : 
    2702           0 :     for( i = 0; i < m_nUsed; i++ )
    2703             :     {
    2704           0 :         aColor[i].red = aColor[i].green = aColor[i].blue = 0;
    2705           0 :         aColor[i].pixel = i;
    2706             :     }
    2707             : 
    2708           0 :     XQueryColors( m_pDisplay->GetDisplay(), m_hColormap, aColor, m_nUsed );
    2709             : 
    2710           0 :     for( i = 0; i < m_nUsed; i++ )
    2711             :     {
    2712           0 :         m_aPalette[i] = MAKE_SALCOLOR( aColor[i].red   >> 8,
    2713             :                                        aColor[i].green >> 8,
    2714           0 :                                        aColor[i].blue  >> 8 );
    2715             :     }
    2716             : 
    2717           0 :     delete [] aColor;
    2718           0 : }
    2719             : 
    2720             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2721           0 : static sal_uInt16 sal_Lookup( const std::vector<SalColor>& rPalette,
    2722             :                                 int r, int g, int b,
    2723             :                                 Pixel nUsed )
    2724             : {
    2725           0 :     sal_uInt16 nPixel = 0;
    2726           0 :     int    nBest  = ColorDiff( rPalette[0], r, g, b );
    2727             : 
    2728           0 :     for( sal_uInt16 i = 1; i < nUsed; i++ )
    2729             :     {
    2730           0 :         int n = ColorDiff( rPalette[i], r, g, b );
    2731             : 
    2732           0 :         if( n < nBest )
    2733             :         {
    2734           0 :             if( !n )
    2735           0 :                 return i;
    2736             : 
    2737           0 :             nPixel = i;
    2738           0 :             nBest  = n;
    2739             :         }
    2740             :     }
    2741           0 :     return nPixel;
    2742             : }
    2743             : 
    2744           0 : void SalColormap::GetLookupTable()
    2745             : {
    2746           0 :     m_aLookupTable = std::vector<sal_uInt16>(16*16*16);
    2747             : 
    2748           0 :     int i = 0;
    2749           0 :     for( int r = 0; r < 256; r += 17 )
    2750           0 :         for( int g = 0; g < 256; g += 17 )
    2751           0 :             for( int b = 0; b < 256; b += 17 )
    2752           0 :                 m_aLookupTable[i++] = sal_Lookup( m_aPalette, r, g, b, m_nUsed );
    2753           0 : }
    2754             : 
    2755             : // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    2756           0 : SalColor SalColormap::GetColor( Pixel nPixel ) const
    2757             : {
    2758           0 :     if( m_nBlackPixel == nPixel ) return SALCOLOR_BLACK;
    2759           0 :     if( m_nWhitePixel == nPixel ) return SALCOLOR_WHITE;
    2760             : 
    2761           0 :     if( m_aVisual.GetVisual() )
    2762             :     {
    2763           0 :         if( m_aVisual.GetClass() == TrueColor )
    2764           0 :             return m_aVisual.GetTCColor( nPixel );
    2765             : 
    2766           0 :         if( m_aPalette.empty()
    2767             :             && m_hColormap
    2768           0 :             && m_aVisual.GetDepth() <= 12
    2769           0 :             && m_aVisual.GetClass() == PseudoColor )
    2770           0 :             ((SalColormap*)this)->GetPalette();
    2771             :     }
    2772             : 
    2773           0 :     if( !m_aPalette.empty() && nPixel < m_nUsed )
    2774           0 :         return m_aPalette[nPixel];
    2775             : 
    2776           0 :     if( m_hColormap )
    2777             :     {
    2778             :         DBG_ASSERT( 1, "SalColormap::GetColor() !hColormap_\n" );
    2779           0 :         return nPixel;
    2780             :     }
    2781             : 
    2782             :     // DirectColor, StaticColor, StaticGray, GrayScale
    2783             :     XColor aColor;
    2784             : 
    2785           0 :     aColor.pixel = nPixel;
    2786             : 
    2787           0 :     XQueryColor( m_pDisplay->GetDisplay(), m_hColormap, &aColor );
    2788             : 
    2789           0 :     return MAKE_SALCOLOR( aColor.red>>8, aColor.green>>8, aColor.blue>>8 );
    2790             : }
    2791             : 
    2792           0 : inline sal_Bool SalColormap::GetXPixel( XColor &rColor,
    2793             :                                           int     r,
    2794             :                                           int     g,
    2795             :                                           int     b ) const
    2796             : {
    2797           0 :     rColor.red      = r * 257;
    2798           0 :     rColor.green    = g * 257;
    2799           0 :     rColor.blue     = b * 257;
    2800           0 :     return XAllocColor( GetXDisplay(), m_hColormap, &rColor );
    2801             : }
    2802             : 
    2803           0 : sal_Bool SalColormap::GetXPixels( XColor &rColor,
    2804             :                                     int     r,
    2805             :                                     int     g,
    2806             :                                     int     b ) const
    2807             : {
    2808           0 :     if( !GetXPixel( rColor, r, g, b ) )
    2809           0 :         return sal_False;
    2810           0 :     if( rColor.pixel & 1 )
    2811           0 :         return sal_True;
    2812           0 :     return GetXPixel( rColor, r^0xFF, g^0xFF, b^0xFF );
    2813             : }
    2814             : 
    2815           0 : Pixel SalColormap::GetPixel( SalColor nSalColor ) const
    2816             : {
    2817           0 :     if( SALCOLOR_NONE == nSalColor )  return 0;
    2818           0 :     if( SALCOLOR_BLACK == nSalColor ) return m_nBlackPixel;
    2819           0 :     if( SALCOLOR_WHITE == nSalColor ) return m_nWhitePixel;
    2820             : 
    2821           0 :     if( m_aVisual.GetClass() == TrueColor )
    2822           0 :         return m_aVisual.GetTCPixel( nSalColor );
    2823             : 
    2824           0 :     if( m_aLookupTable.empty() )
    2825             :     {
    2826           0 :         if( m_aPalette.empty()
    2827             :             && m_hColormap
    2828           0 :             && m_aVisual.GetDepth() <= 12
    2829           0 :             && m_aVisual.GetClass() == PseudoColor ) // what else ???
    2830           0 :             ((SalColormap*)this)->GetPalette();
    2831             : 
    2832           0 :         if( !m_aPalette.empty() )
    2833           0 :             for( Pixel i = 0; i < m_nUsed; i++ )
    2834           0 :                 if( m_aPalette[i] == nSalColor )
    2835           0 :                     return i;
    2836             : 
    2837           0 :         if( m_hColormap )
    2838             :         {
    2839             :             // DirectColor, StaticColor, StaticGray, GrayScale (PseudoColor)
    2840             :             XColor aColor;
    2841             : 
    2842           0 :             if( GetXPixel( aColor,
    2843             :                            SALCOLOR_RED  ( nSalColor ),
    2844             :                            SALCOLOR_GREEN( nSalColor ),
    2845           0 :                            SALCOLOR_BLUE ( nSalColor ) ) )
    2846             :             {
    2847           0 :                 if( !m_aPalette.empty() && !m_aPalette[aColor.pixel] )
    2848             :                 {
    2849           0 :                     const_cast<SalColormap*>(this)->m_aPalette[aColor.pixel] = nSalColor;
    2850             : 
    2851           0 :                     if( !(aColor.pixel & 1) && !m_aPalette[aColor.pixel+1] )
    2852             :                     {
    2853             :                         XColor aInversColor;
    2854             : 
    2855           0 :                         SalColor nInversColor = nSalColor ^ 0xFFFFFF;
    2856             : 
    2857             :                         GetXPixel( aInversColor,
    2858             :                                    SALCOLOR_RED  ( nInversColor ),
    2859             :                                    SALCOLOR_GREEN( nInversColor ),
    2860           0 :                                    SALCOLOR_BLUE ( nInversColor ) );
    2861             : 
    2862           0 :                         if( !m_aPalette[aInversColor.pixel] )
    2863           0 :                             const_cast<SalColormap*>(this)->m_aPalette[aInversColor.pixel] = nInversColor;
    2864             : #ifdef DBG_UTIL
    2865             :                         else
    2866             :                             fprintf( stderr, "SalColormap::GetPixel() 0x%06lx=%lu 0x%06lx=%lu\n",
    2867             :                                      static_cast< unsigned long >(nSalColor), aColor.pixel,
    2868             :                                      static_cast< unsigned long >(nInversColor), aInversColor.pixel);
    2869             : #endif
    2870             :                     }
    2871             :                 }
    2872             : 
    2873           0 :                 return aColor.pixel;
    2874             :             }
    2875             : 
    2876             : #ifdef DBG_UTIL
    2877             :             fprintf( stderr, "SalColormap::GetPixel() !XAllocColor %lx\n",
    2878             :                      static_cast< unsigned long >(nSalColor) );
    2879             : #endif
    2880             :         }
    2881             : 
    2882           0 :         if( m_aPalette.empty() )
    2883             :         {
    2884             : #ifdef DBG_UTIL
    2885             :             fprintf( stderr, "SalColormap::GetPixel() Palette empty %lx\n",
    2886             :                      static_cast< unsigned long >(nSalColor));
    2887             : #endif
    2888           0 :             return nSalColor;
    2889             :         }
    2890             : 
    2891           0 :         ((SalColormap*)this)->GetLookupTable();
    2892             :     }
    2893             : 
    2894             :     // Colormatching ueber Palette
    2895           0 :     sal_uInt16 r = SALCOLOR_RED  ( nSalColor );
    2896           0 :     sal_uInt16 g = SALCOLOR_GREEN( nSalColor );
    2897           0 :     sal_uInt16 b = SALCOLOR_BLUE ( nSalColor );
    2898             :     return m_aLookupTable[ (((r+8)/17) << 8)
    2899             :                          + (((g+8)/17) << 4)
    2900           0 :                          +  ((b+8)/17) ];
    2901             : }
    2902             : 
    2903             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10