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