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