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