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