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